malloc上的struct*和char*分段错误
以下是我遇到问题的代码: 结构:malloc上的struct*和char*分段错误,c,struct,char,segmentation-fault,malloc,C,Struct,Char,Segmentation Fault,Malloc,以下是我遇到问题的代码: 结构: struct AtoB { char * strA; char * strB; }; 函数创建结构。从外部文件调用 AtoB * atob_create(char * a) { struct AtoB * atob = (struct AtoB *)malloc(sizeof(struct AtoB)); atob->strA = malloc(sizeof((char *)a)); strcpy(atob->
struct AtoB
{
char * strA;
char * strB;
};
函数创建结构。从外部文件调用
AtoB * atob_create(char * a)
{
struct AtoB * atob = (struct AtoB *)malloc(sizeof(struct AtoB));
atob->strA = malloc(sizeof((char *)a));
strcpy(atob->strA, a);
atob->strB = NULL;
/* HERE IS PROBLEM NO 1 - SEGMENTATION ERROR OCCURS */
atob->strB = (char*)malloc(1);
strB = "\0";
for(int i = 0; i < (int)strlen(atob->strA); i++)
{
char token = atob->strA[i];
/*
:
append(AtoB * atob, const char a) MAY be called, so atob->strB &
atob->StrA will not be the same length
*/
append(atob, (char)token);
}
}
char * (AtoB * atob)
{
return (atob->strB);
}
void free(AtoB * atob)
{
free(atob->strA);
free(atob->strB);
free(atob);
}
函数来检索最后一个字符串。从外部文件调用
AtoB * atob_create(char * a)
{
struct AtoB * atob = (struct AtoB *)malloc(sizeof(struct AtoB));
atob->strA = malloc(sizeof((char *)a));
strcpy(atob->strA, a);
atob->strB = NULL;
/* HERE IS PROBLEM NO 1 - SEGMENTATION ERROR OCCURS */
atob->strB = (char*)malloc(1);
strB = "\0";
for(int i = 0; i < (int)strlen(atob->strA); i++)
{
char token = atob->strA[i];
/*
:
append(AtoB * atob, const char a) MAY be called, so atob->strB &
atob->StrA will not be the same length
*/
append(atob, (char)token);
}
}
char * (AtoB * atob)
{
return (atob->strB);
}
void free(AtoB * atob)
{
free(atob->strA);
free(atob->strB);
free(atob);
}
函数释放所有分配的内存。从外部文件调用
AtoB * atob_create(char * a)
{
struct AtoB * atob = (struct AtoB *)malloc(sizeof(struct AtoB));
atob->strA = malloc(sizeof((char *)a));
strcpy(atob->strA, a);
atob->strB = NULL;
/* HERE IS PROBLEM NO 1 - SEGMENTATION ERROR OCCURS */
atob->strB = (char*)malloc(1);
strB = "\0";
for(int i = 0; i < (int)strlen(atob->strA); i++)
{
char token = atob->strA[i];
/*
:
append(AtoB * atob, const char a) MAY be called, so atob->strB &
atob->StrA will not be the same length
*/
append(atob, (char)token);
}
}
char * (AtoB * atob)
{
return (atob->strB);
}
void free(AtoB * atob)
{
free(atob->strA);
free(atob->strB);
free(atob);
}
作为练习,我需要使用C并获取一个字符串的内容,以不同的顺序复制它,或者根据此处不存在的问题(因此不包括在代码中)省略或添加某些字符
我在创建结构或分配第一个char*strA
时没有遇到问题。当我试图将内存(甚至一个字符)分配给char*strB
时,问题就出现了
我得到一个分割错误
我怎么做似乎无关紧要,我读过各种各样的例子,尝试过各种各样的方法,但我就是无法让它发挥作用。我知道这里有一些记忆问题,但我似乎无法解决它
即使我尝试realloc
该结构,我也无法将strB
初始化为NULL
以外的任何值。我需要能够在运行时追加到atob->strB
,字符串的最终长度与atob->strA
的长度不同
下面的例子在线,我认为这(作为最简单的初始化)将工作。。。但事实并非如此:
atob->strB = NULL;
atob->strB = (char*)malloc(1);
atob->strB[0] "\0";
这和它所在的结构有关吗
我真的想不起来哪里出了问题,我已经浪费了很多时间在各种论坛上搜索类似的问题,围绕这个主题阅读,尝试每一个我能尝试的解决方案,只是试图通过第一个问题
现在我很困惑,没有时间解决这个问题。如果有人能告诉我我需要的实际代码,那么我将能够阅读并理解您所做的事情以及为什么这是正确的方法。我已经在我不清楚的地方发表了评论,非常感谢正确的解决方案 此代码与您认为的不同:
atob->strA = malloc(sizeof((char *)a));
^ sizeof(char *) is fixed. probably 4 or 8.
因此,如果a
指向更长的字符串,则会出现缓冲区溢出
如果您使用的是Linux,最好运行valgrind内存检查器,以确保没有额外的内存处理问题
调试信息:
编译确保使用调试符号编译(将-g添加到gcc命令)
用gdb运行它
$ gdb ./a.out
崩溃后,寻找回溯
(gdb) bt
当你有了它,只要看看哪里崩溃,并试图了解为什么
由于我们正在处理内存处理问题,请使用valgrind:
$ valgrind --leak-check=full ./a.out
查看输出并清除错误。此代码并不像您认为的那样:
atob->strA = malloc(sizeof((char *)a));
^ sizeof(char *) is fixed. probably 4 or 8.
因此,如果a
指向更长的字符串,则会出现缓冲区溢出
如果您使用的是Linux,最好运行valgrind内存检查器,以确保没有额外的内存处理问题
调试信息:
编译确保使用调试符号编译(将-g添加到gcc命令)
用gdb运行它
$ gdb ./a.out
崩溃后,寻找回溯
(gdb) bt
当你有了它,只要看看哪里崩溃,并试图了解为什么
由于我们正在处理内存处理问题,请使用valgrind:
$ valgrind --leak-check=full ./a.out
查看输出并清除错误。将strB初始化为空字符串时,使用:
strB = "\0";
但您应该使用以下任一选项:
strB = '\0';
或:
字符串literal“\0”
是由三个字符组成的数组
:{'\','0','\0'}
。您在其他地方也做了同样的事情(这里看起来您遗漏了struct
字段的名称):
并且(这里我假设您意外遗漏了赋值运算符):
您增长字符串的方式存在问题strlen()
给出了num
终止符之前数组中char
s的数量,因此如果您想添加另一个char
您需要为sz+2
chars分配。然后新的char
需要放在strB[sz]
处,这是旧的NUL
所在的位置,而NUL
需要放在字符串的末尾,这就是strB[sz+1]
。
通过将代码更改为以下内容,您可以NUL
终止字符串strB
:
atob->strB = realloc(atob->strB, sz + 2);
atob->strB[sz] = a;
atob->strB[sz + 1] = '\0';
另外,realloc()
可能返回NULL
,从而导致内存泄漏。您应该使用一个临时变量来存储调用realloc()
的结果:
将strB初始化为空字符串时,使用:
strB = "\0";
但您应该使用以下任一选项:
strB = '\0';
或:
字符串literal“\0”
是由三个字符组成的数组
:{'\','0','\0'}
。您在其他地方也做了同样的事情(这里看起来您遗漏了struct
字段的名称):
并且(这里我假设您意外遗漏了赋值运算符):
您增长字符串的方式存在问题strlen()
给出了num
终止符之前数组中char
s的数量,因此如果您想添加另一个char
您需要为sz+2
chars分配。然后新的char
需要放在strB[sz]
处,这是旧的NUL
所在的位置,而NUL
需要放在字符串的末尾,这就是strB[sz+1]
。
通过将代码更改为以下内容,您可以NUL
终止字符串strB
:
atob->strB = realloc(atob->strB, sz + 2);
atob->strB[sz] = a;
atob->strB[sz + 1] = '\0';
另外,realloc()
可能返回NULL
,从而导致内存泄漏。您应该使用一个临时变量来存储调用realloc()
的结果:
您不需要键入cast来调用malloc。大多数C++程序员都这样做,这是不必要的。你能使用调试器并显示你的崩溃的后跟踪吗?为什么要对此进行投票?