当我遇到这个时,我正在学习C并且在堆内存中玩了一下:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* test = malloc(1024);
test = "Hello!";
printf("%s\n", test);
free(test);
return 0;
}
我认为它应该做什么:
stdout
获得的指针开头写入malloc()
,直至找到\0
malloc()
但是,我的程序在调用free()
时崩溃了。为什么呢?
~$ ./mem
Hello!
*** Error in `./mem': munmap_chunk(): invalid pointer: 0x0000000000400684 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f9f99ac5725]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7f9f99ad1c18]
./mem[0x4005ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f9f99a6e830]
./mem[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 3801151 /home/gala/mem
00600000-00601000 r--p 00000000 08:01 3801151 /home/gala/mem
00601000-00602000 rw-p 00001000 08:01 3801151 /home/gala/mem
015e6000-01607000 rw-p 00000000 00:00 0 [heap]
7f9f99838000-7f9f9984e000 r-xp 00000000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f9984e000-7f9f99a4d000 ---p 00016000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4d000-7f9f99a4e000 rw-p 00015000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4e000-7f9f99c0e000 r-xp 00000000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99c0e000-7f9f99e0d000 ---p 001c0000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e0d000-7f9f99e11000 r--p 001bf000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e11000-7f9f99e13000 rw-p 001c3000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e13000-7f9f99e17000 rw-p 00000000 00:00 0
7f9f99e17000-7f9f99e3d000 r-xp 00000000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a013000-7f9f9a016000 rw-p 00000000 00:00 0
7f9f9a039000-7f9f9a03c000 rw-p 00000000 00:00 0
7f9f9a03c000-7f9f9a03d000 r--p 00025000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03d000-7f9f9a03e000 rw-p 00026000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03e000-7f9f9a03f000 rw-p 00000000 00:00 0
7ffcc81cb000-7ffcc81ec000 rw-p 00000000 00:00 0 [stack]
7ffcc81f8000-7ffcc81fa000 r--p 00000000 00:00 0 [vvar]
7ffcc81fa000-7ffcc81fc000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[1] 12941 abort ./mem
答案 0 :(得分:3)
欢迎来到C的复杂世界!
基本上,您使用地址test
覆盖指针"Hello!"
(这是静态不可变数组)。
它崩溃了,因为你试图释放一个你没有创造的东西。
您应该使用strcpy()
或循环将字符串复制到text
。
答案 1 :(得分:3)
正如评论中所说的那样:
int main(void) {
char* test = malloc(1024); /* You allocate, great! */
test = "Hello!"; /* Huh, what's this? You point 'test'
* to some area in the code section.
* Valid, but considering you just
* allocated some memory, strange */
printf("%s\n", test); /* Print out a string from the code
* section: fine. */
free(test); /* What?! You want to try to free() the
* memory in the code section? That's a
* big no-no! */
return 0; /* whatever */
}
现在,你应该做什么:
int main(void) {
char* test = malloc(1024); /* You allocate, great! */
strcpy(test, "Hello!"); /* Copy some data into that
* allocated memory */
printf("%s\n", test); /* Print out a string from the
* heap: fine. */
free(test); /* Free that allocated memory! */
return 0; /* aaaand, we're done */
}
答案 2 :(得分:1)
test最初指向由大小为1024的malloc分配的内存。 现在在下一行中,您将测试指向由“Hello!”引用的内存。 所以你的测试指针现在指向“你好!”而不是你首先使用malloc分配的内容。 现在你试图释放“Hello!”,这是无效的,因为没有使用malloc分配这个内存,因此你的编程崩溃了。
public class SpinnerFragment extends Fragment {
/*private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;*/
private OnFragmentInteractionListener mListener;
private View rootView;
private SearchView teamsSearchView;
private PopupWindow popupMessage;
private ArrayAdapter<String> adapter;
public SpinnerFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SpinnerFragment.
*/
public static SpinnerFragment newInstance(String param1, String param2) {
SpinnerFragment fragment = new SpinnerFragment();
/*Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);*/
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}*/
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_spinner, container, false);
TextView textView = new TextView(getActivity());
textView.setText("Testing");
View popup_layout = inflater.inflate(R.layout.popup_layout,container,false);
ListView teamsListView = (ListView) popup_layout.findViewById(R.id.teams_list_view);
ArrayList<Team> teamsArrayList = new ArrayList<Team>();
teamsArrayList.add(new Team(1,"Sharks"));
teamsArrayList.add(new Team(2,"Android"));
teamsArrayList.add(new Team(3,"Google"));
teamsArrayList.add(new Team(4,"Yahoo"));
teamsArrayList.add(new Team(5,"Facebook"));
teamsArrayList.add(new Team(6,"Twitter"));
teamsArrayList.add(new Team(7,"Apple"));
teamsArrayList.add(new Team(8,"Amazon"));
teamsArrayList.add(new Team(9,"Udacity"));
teamsArrayList.add(new Team(10,"Bosch"));
//adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line,sortList);
final TeamsAdapter teamsAdapter = new TeamsAdapter(getActivity(), teamsArrayList);
teamsListView.setAdapter(teamsAdapter);
popupMessage = new PopupWindow(popup_layout, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
//popupMessage.setContentView(textView);
teamsSearchView = (SearchView) rootView.findViewById(R.id.teams_search_view);
teamsSearchView.setQueryHint("Select Team/s");
teamsSearchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
Toast.makeText(getActivity(), String.valueOf(hasFocus),
Toast.LENGTH_SHORT).show();
}
});
teamsSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(getActivity(), query,
Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
Toast.makeText(getActivity(), "newText=>"+newText,
Toast.LENGTH_SHORT).show();
if(newText.isEmpty()){
popupMessage.dismiss();
return false;
}
//popupMessage.dismiss();
if(!popupMessage.isShowing()){
popupMessage.showAsDropDown(teamsSearchView);
}
teamsAdapter.getFilter().filter(newText);
/*teamsAdapter.getFilter().filter(newText, new Filter.FilterListener() {
@Override
public void onFilterComplete(int i) {
teamsAdapter.notifyDataSetChanged();
}
});*/
return true;
}
});
return rootView;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction();
}
}
存储“你好!”在test分配的内存中,需要使用memcpy。 所以代替:
char* test = malloc(1024);
test = "Hello!"; /* This is wrong. You pointer is pointing to "Hello!" string base address */
使用:
test = "Hello!"
这将修复您的代码。