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++程序员都这样做,这是不必要的。你能使用调试器并显示你的崩溃的后跟踪吗?为什么要对此进行投票?