如何解决为什么指针char在结构环境中引起分段错误
我是C的初学者,通常我使用C ++。我尝试使用其中带有struct
数组的char
,但是当我使用另一个char *str
时,它将引发segfault
。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_obj t_obj;
struct s_obj {
char *str;
};
int main() {
char *str; // if disable no segmentation fault
t_obj obj;
printf("%lu\n",strlen(obj.str));
return(0);
}
我试图理解“ strlen
的参数必须是字符串” @anastaciu的意思,所以我试图编写代码来做到这一点,但是结果是一样的:{{ 1}},则使用其他segfault
。
我找不到在结构中初始化char *str
的方法。
char *str
解决方法
行
printf("%lu\n",strlen(obj.str));
调用未定义的行为,strlen
的参数必须是一个字符串,又是一个以null结尾的char数组,obj.str
不是字符串,它只是一个未初始化的指针,您需要分配内存为此,否则将其指向有效的内存位置。
例如:
t_obj obj;
obj.str = calloc(100,sizeof *obj.str); //99 character string,0 initialized
//malloc does not "clear" the allocated memory
//if you use it you can't use strlen before strcpy
printf("%zu\n",strlen(obj.str)); //will print 0,the string is empty
obj.str = strcpy(obj.str,"truc");
printf("%zu\n",strlen(obj.str)); //will print 4,the length of the string
当您删除 char *str;
时,程序的表现不会很差,这完全属于undefined behavior的范围内:
C不是C ++;)似乎您错过了两者的重要区别。
C ++示例:
#include <string>
struct t_obj {
std::string str;
};
void foo(){
t_obj obj; // <-- In C++ this is enough to get a properly initialized instance.
}
在C ++中,此代码将为您提供带有(也已初始化)字符串的正确初始化的对象。
但是在C语言中(如您的示例所示):
typedef struct t_obj t_obj;
struct t_obj {
char *str;
};
void foo(){
t_obj obj; // <-- Nothing gets initialized here.
}
没有上面的C ++示例中的初始化。 obj
将只是(未初始化的)内存块。您必须自己对其进行初始化。
第二个样品也有问题:
strcpy
不能那样工作。我们需要将分配的内存块传递到strcpy
,它将把数据复制到我们给它的那个位置。
但是,当我们传递“未初始化的指针”时,strcpy将尝试在内存中的某个地方写入数据。
我认为问题“ whats the difference between C strings and C++ strings?”可能会有所帮助。它解释了有关C和C ++字符串的区别的一些细节。
,无论哪种情况,您都使用未初始化的obj.str
。
它所保存的地址不确定,并且它指向的内存位置的内容也不确定。因此,它不是以Null结尾的,并且将其与strlen()
(即,使用需要字符串参数的函数)一起使用,将导致超出范围的访问,这实际上是无效的内存访问,进而调用未定义的行为
供参考,C11
,第7.24章,字符串处理<string.h>
[...]除非在本节中对特定功能的描述中另有明确说明,否则此类调用的指针参数仍应具有有效值,[...]
至少,将指针初始化为空值。
,现在代码可以正常工作了:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_obj t_obj;
struct s_obj {
char *str;
};
int main() {
char *str;
t_obj obj;
if (!(obj.str = (char*)malloc(sizeof(char))))
return (0);
obj.str = strcpy(obj.str,"truc");
printf("%s\n",obj.str);
free(obj.str);
return(0);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。