char* leads to segfault but char[] doesn't
我想我知道自己问题的答案,但我想确认一下,我完全理解这个问题。
我编写了一个返回字符串的函数。我传递一个
它工作正常,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> #include <stdlib.h> #include <string.h> void get_file_name(char* file_name_out) { char file_name[12+1]; char dir_name[50+12+1]; strcpy(file_name,"name.xml"); strcpy(dir_name,"/home/user/foo/bar/"); strcat(dir_name, file_name); strcpy(file_name_out, dir_name); // Clarity - equivalent to a return } int main() { char file_name[100]; get_file_name(file_name); printf(file_name); return 0; } |
但是如果我用
我不知道为什么?
我的函数以
据我所知,
但是当我写
它将解释以下代码编译并生成预期输出的原因:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
另一方面,如果我使用
我说的对吗?
As far as I understand, char *filename =""; creates a read-only
string. strcpy() is then trying to write into a read-only variable,
which is not allowed so the error makes sense.
是的,没错。它本质上不同于声明字符数组。将字符指针初始化为字符串文字将使其只读;尝试更改字符串的内容将导致UB。
But what happens when I write char *filename; ? My guess is that
enough space to fit a pointer to a char is allocated on the stack, so
I could write only one single character into my file_name_out
variable.
您分配了足够的空间来存储指向字符的指针,就这样。您不能写入
我想这里的问题是
1 | char string[100]; |
将内存分配给字符串-您可以使用字符串作为指针访问该字符串但是
1 | char * string; |
不会为字符串分配任何内存,因此会出现SEG故障。
为了获得你可以使用的记忆
1 |
例如,但是您需要在末尾记住,以便用
1 |
或者你可能会有内存泄漏。
另一个内存分配路由使用malloc
所以总结一下
1 | char string[100]; |
等于
尽管严格地说calloc将所有元素初始化为零,但是在字符串[100]decalation中,除非使用String〔100〕={}如果使用malloc来对内存进行分级,则内容是未定义的。
@paulrooney提出的另一点是char字符串[100]在堆栈上分配内存,而calloc使用堆。有关堆和堆栈的详细信息,请参阅此问题和答案…
1 | char *filename; |
什么都不分配。它只是指向一个未指定位置的指针(该值是以前内存中的任何值)。使用这个指针永远不会起作用,因为它可能指向您的程序允许使用的内存范围之外。
1 | char *filename =""; |
指向程序数据段的一部分。正如您已经说过的,它是只读的,因此试图更改它会导致segfault。
在最后一个示例中,您处理的是单个