char*导致segfault,但char[]不';T
我想我知道我自己问题的答案,但我想确认我完全理解这一点 我编写了一个返回字符串的函数。我将一个char*导致segfault,但char[]不';T,c,string,segmentation-fault,C,String,Segmentation Fault,我想我知道我自己问题的答案,但我想确认我完全理解这一点 我编写了一个返回字符串的函数。我将一个char*作为参数传递,函数修改指针 它工作正常,下面是代码: #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
char*
作为参数传递,函数修改指针
它工作正常,下面是代码:
#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;
}
另一方面,如果我使用char file_name[100]
,我在堆栈上分配了足够的空间容纳100个字符,因此strcpy()
可以愉快地写入file\u name\u out
我说得对吗
据我所知,char*filename=“”;创建只读
一串然后strcpy()尝试写入只读变量,
这是不允许的,因此错误是有意义的
是的,没错。它本质上不同于声明字符数组。初始化字符串文本的字符指针使其为只读;试图更改字符串的内容将导致UB
但是当我写char*filename;,会发生什么呢?我猜是这样
堆栈上分配了足够的空间来容纳指向字符的指针,因此
我只能在文件名中写一个字符
变数
分配足够的空间来存储指向字符的指针,就这样。您不能写入
*filename
,甚至不能写入一个字符,因为您没有分配空间来存储*filename
指向的内容。如果要更改文件名所指向的内容,首先必须将其初始化为指向有效的位置。字符文件名[100]代码>创建100个字符的连续数组。在本例中,file\u name
是一个类型为(char*)的指针,它指向数组中的第一个元素
char*文件名代码>创建指针。但是,它没有初始化为特定的内存地址。此外,这个表达式不分配内存。我认为这里的问题是
char string[100];
将内存分配给字符串-您可以使用字符串作为指针访问该字符串
但是
不会为字符串分配任何内存,因此会出现seg错误
要获得内存,您可以使用
string = calloc(100,sizeo(char));
例如,但您需要在最后记住以释放内存
free(string);
或者你可能会出现内存泄漏
另一个内存分配路由是malloc
总而言之
char string[100];
相当于
char * string;
string = calloc(100,sizeo(char));
...
free(string);
虽然严格来说,calloc将所有元素初始化为零,但在字符串[100]十进制中,数组元素未定义,除非使用
字符串[100]={}
如果使用malloc对内存进行分级,则内容未定义
@PaulRooney提出的另一点是,char string[100]给出堆栈上的内存分配,而calloc使用堆
什么也不分配。它只是一个指向未指定位置的指针(该值是该内存中以前的值)。使用此指针将永远无法工作,因为它可能指向您的程序允许使用的内存范围之外
char *filename = "";
指向一段程序数据段。正如您已经说过的,它是只读的,因此尝试更改它会导致SEGFULT
在最后一个示例中,您处理的是单个char
值,而不是char值字符串,并且您的函数foo
将它们视为单个值。因此,char*值指向的缓冲区长度没有问题。“但是如果我将char file_name[100];替换为char*filename;或char*filename=“”;则strcpy()中会出现分段错误。“-char*filename没有分配内存;这只是一个指针看看内存分配,在malloc
函数中以及如何使用它。“我猜堆栈上分配了足够的空间来容纳指向字符的指针,所以我只能写一个字符”-第一部分正确,第二部分错误。指针的值是它所持有的地址。。声明一个而不初始化会使指针不确定。它不包含有效内存区域的已知地址。取消引用它会调用未定义的行为(阅读或写作没有区别)。啊,是的,我编辑了这个问题。所以这是正确的说法:如果我定义了变量指向的位置,我可以在变量指向的地方写一个字符。在这种情况下,file_name是一个类型为(char*)的指针。不是真的<代码>文件名
的类型为char[100]
。数组和指针并不总是可互换的。可以说,在大多数情况下,file\u name
将衰减为指向第一个元素的指针。但它不是指向char的指针。如果文件名
是一个字符*
,那么文件名
将是一个字符**
,而事实上它是一个字符(*)[100]
。注意字符字符串[100]之间的差异可能也很重要代码>和calloc
分配是一个在堆栈上,而另一个在堆上。谢谢@PaulRooney-将编辑放入。。。
char * string;
string = calloc(100,sizeo(char));
...
free(string);
char *filename;
char *filename = "";