【问题标题】:Can't solve memory management (valgrind) in this c program在这个 c 程序中无法解决内存管理(valgrind)
【发布时间】:2019-06-09 13:56:29
【问题描述】:

我的问题如下。我必须创建一个 C 程序,将输入中的所有参数连接到一个缓冲区中,然后返回这个缓冲区。我的解决方案有效,但存在内存管理问题。

我该如何解决这个问题?

#define RIALLOCA(buf, newsize) buf = realloc(buf, newsize);

char *mystrcat(char *buf, size_t sz, char *first, ...) {
    va_list l;
    va_start(l, first);

    buf = malloc(strlen(buf) + 1);

    if (sz < strlen(first) + 1) {
        sz += (strlen(first) + 1);
    }

    RIALLOCA(buf, sz + 1 + 16);
    strncat(buf, first, strlen(first));

    char *nextString = va_arg(l, char *);

    while (nextString != NULL) { 
        // sz += strlen(nextString);
        RIALLOCA(buf, strlen(buf) + strlen(nextString) + 1 + 16);
        strncat(buf, nextString, strlen(nextString));
        nextString = va_arg(l, char *);
    }   

    va_end(l);

    return buf;
}   

int main(int argc, char *argv[]) {
    if (argc != 7) {
        printf("troppi pochi argomenti\n");
        return -1; 
    }   
    char *buffer = NULL;
    RIALLOCA(buffer, 16);  // macro che effettua l'allocazione
    buffer[0] = '\0';
    buffer = mystrcat(buffer, 16, argv[1], argv[2], argv[3], argv[4], argv[5],
                      argv[6], NULL);
    printf("%s\n", buffer);
    free(buffer);     
    return 0;
}

这是 Valgrind 的问题

【问题讨论】:

  • 不要发布图片链接。而是将文本复制/粘贴到您的问题中。
  • 为 C 库函数生成“替换”函数(或 #defines)是浪费您(和我们)的时间
  • 在调用任何堆分配函数时:malloc()calloc()realloc(), 1) 始终检查 (!=NULL) 返回值以确保操作成功。 2) 在调用realloc()时,总是将结果赋值给一个临时指针然后检查(!=NULL),否则当realloc()失败时,原始指针丢失,导致不可恢复的内存泄漏
  • OT:为了便于阅读和理解:1) 请始终缩进代码。在每个左大括号 '{' 后缩进。在每个右大括号 '}' 之前取消缩进。建议每个缩进级别为 4 个空格。
  • 发布代码时,请发布#include语句,这样我们就无法猜测您的代码实际包含哪些头文件

标签: c memory-leaks valgrind


【解决方案1】:

问题在于 - 当您在 mystrcat() 内调用 buf = malloc() 时 - 您会导致内存泄漏。内存已在您的main() 中为buf 动态分配。

改变

buf = malloc(strlen(buf)+1);

buf = realloc(buf, strlen(buf) + 1);

另外......我同意 user3629249:以您所做的方式为标准库函数提供宏似乎是多余的 - 至少在这种情况下。

【讨论】:

    【解决方案2】:

    在函数中:mystrcat()

    此声明:

    buf = malloc(strlen(buf) + 1);
    

    不正确。因为buf 已经是一个指向已分配内存的指针,而且这不是在修改main() 函数中的指针buf,而只是修改堆栈上的参数。

    纠正:

    main() 中(注意额外的“&”参数:buffer

    buffer = mystrcat(&buffer, 16, argv[1], argv[2], argv[3], argv[4], 
    argv[5], argv[6], NULL);
    

    mystrcat() 中删除此行

    buf = malloc(strlen(buf) + 1);
    

    关于:

    if(sz < strlen(first) + 1)
    {
        sz += (strlen(first) + 1);
    }
    

    因为sz 包含 16 并且buf 中的第一个字符是 '\0' 这个if() 语句永远不会被输入。

    由于传递的参数buf现在是指向指针的指针,由于main()的变化,签名应该是:

    char* mystrcat(char **buf, size_t sz, char *first, ...) 
    

    并且所有对buf 的引用都应该取消引用该参数以访问main() 中的指针值

    还有很多,但以上是根本问题

    【讨论】:

      猜你喜欢
      • 2013-03-25
      • 2021-05-23
      • 2016-02-09
      • 1970-01-01
      • 2013-02-05
      • 2021-08-23
      • 2014-01-21
      • 2012-05-11
      • 1970-01-01
      相关资源
      最近更新 更多