【问题标题】:Getting Segmentation Fault in Realloc在 Realloc 中获取分段错误
【发布时间】:2012-01-30 15:05:28
【问题描述】:

在这里我想创建动态内存。 这里我不知道输出大小,我想在 while 循环之后打印最后的最终输出。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main() {

    char *sdpCommand = "sdptool browse 04:18:0F:B1:48:B5";

    FILE *fp;
    fp = popen(sdpCommand, "r");

    char *results = 0;
    if (fp == NULL) {
        printf("Failed to run command\n");
        return;
    }

    char* buffer = malloc(514);
    while (fgets(buffer, strlen(buffer) - 1, fp) != NULL) {
        realloc(results, strlen(results) + strlen(buffer));
        memcpy(results + strlen(results), buffer, strlen(buffer));
    }
    printf("Output    :::  %s", results);

    /* close */
    pclose(fp);
    sleep(1);

}

【问题讨论】:

    标签: c


    【解决方案1】:

    主要有两个问题:

    1. realloc() 返回新地址:

      new_results = realloc(results, ...);
      if (new_results != NULL) {
        results = new_results;
      } else {
        /* handle reallocation failure, `results' is still valid */
      }
      
    2. sizeof() 不是找出resultsbuffer 大小的正确方法。它只会返回指针的大小。对于results,您可能希望自己跟踪分配的大小。对于buffer,您可能正在寻找strlen()

    修复上述问题后,您需要确保 results 以有效的 NUL 结尾字符串结束。这是printf() 正常工作所必需的。

    【讨论】:

    • ... 或 NULL 如果分配失败。
    • 详细来说,sizeof(results)sizeof(buffer) 返回在编译时实际已知的指针大小。标准 C 中没有办法查询动态分配的内存块的大小。因此,您必须记住分配了多少。
    • 你能告诉我我必须在哪里改变事情并且我的代码工作正常吗?
    • 您的第 1 点应该提到将 realloc 的返回值直接分配回指针变量是一种可怕的做法。您必须首先检查它没有失败...
    • @user1089679 如果我们为您做,您将不会学到任何东西。你需要了解。
    【解决方案2】:

    您的代码只是盲目地向前推进,似乎是根据“它编译,它必须工作”范式编写的。很抱歉,如果这听起来很苛刻,这当然不是针对您个人的评论。

    您需要真正查看您尝试使用的 API 的文档,并分析您的使用是否有意义。

    你不能忽略来自realloc()的返回值,你将如何获得新分配的内存?它不能改变你现有的指针,因为你是按值传递的。

    动态数组的工作方式通常需要跟踪三件事:

    • 当前数组的基地址
    • 数组现在包含的元素数(在您的情况下为字节数)
    • 数组可以容纳的最大元素数(在它需要增长之前)

    当添加 n 个新元素时,检查这样做是否会溢出元素数量,因此它会大于最大值。这是不允许的,因此在这种情况下,您需要重新分配基本数组以适应新数据,并且(当然)相应地更新数组的状态。

    【讨论】:

      【解决方案3】:

      realloc(results, sizeof(results) + sizeof(buffer));

      这条线可能是问题所在。

      1. realloc() 返回分配给指定大小的新地址,并且不能保证它与指针之前的地址相同;所以,你应该总是重新分配你的指针:

        ptr = realloc(ptr, newSize);

      2. sizeof() 不会返回指针的动态分配大小。在这种情况下,sizeof(results)sizeof(buffer) 很可能总是返回 8。您可以替换为:

        results = realloc(results, ctr * 514);
        其中 ctr 是 short,在 while 之前用 0 初始化并计算迭代次数。

      3. 既然缓冲区总是 514,为什么不通过重新定义来减少负载:

        字符缓冲区[514];

        最好的问候

      【讨论】:

      • 将 0 分配给指针是完全有效的,标准要求编译器在这些情况下将 NULL 分配给指针。
      猜你喜欢
      • 2014-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-05
      • 2021-07-19
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      相关资源
      最近更新 更多