如何使malloc成为另一个结构内的结构?

时间:2017-11-24 16:46:21

标签: c struct malloc

在第一个.h文件中,我有这个结构:

typedef struct system
{
    char* name;
    DArray Info;
} *System;

.c文件中我有这个功能:

System createSystem(char *name){
    if (!name){
        return NULL;
    }
    System newSystem=malloc(sizeof(*newSystem));
    if (!newSystem){
        return NULL;
    }
    newSystem->name=malloc(sizeof(strlen(name)+1));
    if (!newSystem->name){
       free(newSystem);
       return NULL;
    }
    strcpy(newSystem->name,name);
    newSystem->Info=malloc(sizeof *(newSystem->Info));
        if (!newSystem->Info){
            free(newSystem->name);
            free(newSystem);
            return NULL;
        }
        newSystem->Info->x=0;
        newSystem->Info->elements=NULL;
    return newSystem;
}

在另一个.h文件中,我有struct dArray

typedef struct dArray
{
   int x;
    Element *elements;
} *DArray;

其中Element可以是任何类型。

但是,该函数始终在Eclipse中停止工作,我收到错误

  

hw停止工作

我知道问题出在这一行:

 newSystem->Info=malloc(sizeof(*newSystem->Info));

但是我不明白为什么这是一个问题,因为我试图以常规方式将{malloc}传递给struct DArray

我一直在主文件中使用此测试:

int main() {
sys=createSystem("ss1");
if (sys) {
printf ("ok");
return 0;
}

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:0)

System createSystem(char *name){
    if (!name){
        return NULL;
    }
    System newSystem=malloc(sizeof *newSystem);
    if (!newSystem){
        return NULL;
    }
    newSystem->name=malloc(sizeof *newSystem->name * (strlen(name)+1)); // <-- change here.
    if (!newSystem->name){
       free(newSystem);
       return NULL;
    }
    strcpy(newSystem->name,name);
    newSystem->Info=malloc(sizeof *newSystem->Info);
        if (!newSystem->Info){
            free(newSystem->name);
            free(newSystem);
            return NULL;
        }
        newSystem->Info->x=0;
        newSystem->Info->elements=NULL;
    return newSystem;
}

如果要将字符串复制到动态分配的内存,它(malloc)基本上会分配sizeof (strlen(str)+1)个字节的内存。除了sizeof运算符应用于size_t之外,它不会包含字符串。 (我的机器中有5个字符)。 (为什么size_t?因为函数strlen有一个签名size_t strlen(const char *s);

同样在我的系统中sizeof size_t是4个字节。所以基本上你分配5个字节。这意味着字符串将由5个字符组成,包括nul终止字符。

任何超过长度的东西都更像"ABCDED",你正在写出你分配的内存导致非法内存访问 - 这有不确定的行为。在你的情况下,它只是停止。

为了添加更多说明,在您的情况下,我猜您在输入字符串时传递的内容超过4长度。但是如果你传递字符串"ss1",那么这将有效。

newSystem->name=malloc(sizeof *newSystem->name * (strlen(name)+1));可以更清楚地写为newSystem->name=malloc(strlen(name)+1);。由于sizeof char1字节,我们已经避免了它。

您稍后可能会尝试查找不属于ISO标准的strdup功能。

答案 1 :(得分:0)

以下陈述不正确: -

System newSystem=malloc(sizeof(*newSystem));它应该是系统newSystem=malloc(sizeof(struct system));

newSystem->Info=malloc(sizeof *(newSystem->Info));newSystem->Info是指针吗?如果指针应该是newSystem->Info=malloc(sizeof(DArray));

答案 2 :(得分:0)

此外,以下内容完全不同于以下内容: newSystem-&GT;名称= malloc的(的sizeof(strlen的(名称)+1));

那就是malloc()一个缓冲区(至少)sizeof(size_t)而不是一个能够保存strlen(name)的缓冲区+1字节 - size_t是strlen的返回类型,这就是sizeof是适用于。