【问题标题】:memory error caused by self created tostring function in C [closed]由 C 中自创的 tostring 函数引起的内存错误 [关闭]
【发布时间】:2021-05-06 17:09:42
【问题描述】:

这是我创建的一个函数,用于将结构的内容打印为单个字符串,基本上它就像一个 tostring 函数。

typedef struct {
    
    char* firstname;

    char* lastname;

    char* address;
    
} info;
char* strucstring(struct* info)
{ 
    char * string = (char*)malloc(sizeof(info->firstname));
    sprintf(string, "%s",info->firstname);
    
    return string;
}

当我这样称呼它时,在我的main 中:

char *string  = strucstring(info);
printf("%s",string);
free(string);

return 0;

没有内存泄漏,但有一些内存错误。 可以看到没有内存泄漏,但在 8 个上下文中出现了 24 个错误。

如何消除这些错误??

【问题讨论】:

  • sizeof(info) 是错误的。你的代码也是错误的,它甚至不能编译;大概你的意思是struct something *info。在任何情况下,您可能是指sizeof info->name,它可以修复它 取决于字符串的声明。最后,既然您似乎在 Unix 系统上,那么请使用 char *string = strdup(info->name) 而不是 malloc/sprintf
  • 什么是info?它的定义不包括在内。不管它是什么,表达式sizeof(info) 将提供指针的大小,可能不是您想要的。提示,将原型更改为 char* strucstring(struct* info, size_t size), and pass the _sizeof_ info` 作为参数。
  • 我进行了编辑。 info 中有很多东西,这就是我使用 malloc(info).. 的原因
  • 如何为所有结构内容(如名字、姓氏和地址)分配一个字符串?我要重新分配吗?
  • @klutt 那么lastnameaddress??

标签: c memory memory-leaks malloc valgrind


【解决方案1】:

原型:char* strucstring(struct* info); 抛出以下错误:

6、19 错误:匿名结构的声明必须是定义
6、19 错误:预期的参数声明符

将其更改为((基于对 typedefed 结构的编辑修改,见下文):

char* strucstring(info_s *info); 

(还有其他错误。编译您的代码并打开警告以查看所有错误。)

假设您的struct 的最小定义:

typedef 结构 { 字符名[80]; 字符姓氏[80]; 字符地址[80]; }info_s;

鉴于您的结构定义(对您的帖子编辑进行了少量修改。)

typedef struct {  
    char* firstname;
    char* lastname;
    char* address;    
} info_s;

在作为参数传递之前,需要填充每个成员。这可以通过多种方式完成,下面使用简单的赋值语句

修改后的代码示例,包括为字符串分配内存的正确方法:(感谢@Jabberwocky,+1)

typedef struct {
    char *firstname;
    char *lastname;
    char *address;
}info_s;

char* strucstring(info_s *info);

int main(void)
{   
    //populate each struct member with content:
    info_s info = {"Roger", "Bains", "1234, Noble Rd, Christchurch"};
    
    char *string  = strucstring(&info);
    printf("%s",string);
    free(string);

    return 0;
}

char* strucstring(info_s *info)
{ 
    int sizeneeded = 1 + snprintf(NULL, 0, "%s %s %s",info->firstname, info->lastname, info->address);
    char * string = malloc(sizeneeded);
    sprintf(string, "%s %s %s",info->firstname, info->lastname, info->address );
    
    return string;
}

还要注意演员表已从malloc() 中删除for these reasons

【讨论】:

    【解决方案2】:

    你这里的内存分配是错误的。 sizeof(info) 是结构的大小,而不是结构中字符串的大小。还有(struct* info)错了,应该是(struct info* info)

    char* strucstring(struct* info)
    { 
        char * string = (char*)malloc(sizeof(info));  // <<< this is wrong
        sprintf(string, "%s %s %s",info->firstname, info->address, info->lastname);    
        return string;
    }
    

    你想要这个:

    char* strucstring(struct info* info)
    { 
        int sizeneeded = 1 + snprintf(NULL, 0, "%s %s %s",info->firstname, info->address, info->lastname);
        // the +1 is for the NUL string terminator
    
        char *string = malloc(sizeneeded);    // the (char*) cast is not needed
        snprintf(string, sizeneeded, "%s %s %s",info->firstname, info->address, info->lastname);    
        return string;
    }
    

    我们使用大小为 0 的缓冲区调用 snprintf。这将返回输出字符串所需的字节数。然后我们分配所需的字节数并使用新分配的缓冲区再次调用snprintf

    免责声明:

    • 为简洁起见,此处未进行错误检查。
    • 在您未显示的代码部分的其他地方可能存在更多问题。

    【讨论】:

    • 您的分配方法是正确的方法。
    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2015-02-23
    相关资源
    最近更新 更多