【问题标题】:C using malloc and realloc to dynamically increase string lengthC 使用 malloc 和 realloc 动态增加字符串长度
【发布时间】:2020-04-13 15:33:11
【问题描述】:

目前正在学习 C 中的内存管理,并且我目前遇到了随着循环迭代而增加字符串长度的问题。

我试图找出逻辑上的方法是这样的:

// return string with "X" removed


char * notX(char * string){

   result = "";

   if(for int = 0; i < strlen(string); i++){
      if (string[i] != 'X') {
         result += string[i];
      }
   }

   return result;
}

在其他语言中足够简单,但在 C 中管理内存却有点挑战性。我遇到的困难是当我使用 malloc 和 realloc 来初始化和更改字符串的大小时。在我目前尝试的代码中:

char * notX(char * string){

   char* res = malloc(sizeof(char*)); // allocate memory for string of size 1;
   res = ""; // attempted to initialize the string. Fairly certain this is incorrect
   char tmp[2]; // temporary string to hold value to be concatenated

   if(for int = 0; i < strlen(string); i++){
      if (string[i] != 'X') {

         res = realloc(res, sizeof(res) + sizeof(char*)); // reallocate res and increasing its size by 1 character
         tmp[0] = string[i];
         tmp[1] = '\0';
         strcat(res, tmp);

      }
   }

   return result;
}

注意,我发现成功初始化结果是一些大数组,例如:

char res[100];

但是,我想了解如何在不初始化具有固定大小的数组的情况下解决此问题,因为这可能会浪费内存空间或内存不足。

【问题讨论】:

  • malloc(sizeof(char*)) = 分配指针的大小。此外,realloc(res, sizeof(res) + sizeof(char*)); 重新分配到 两个 指针总是 的大小。我认为您不了解sizeof 的工作原理。而res = ""; 造成了两场灾难。 (1) 它泄露了前一行分配的内存,(2) 它现在导致res 指向一个常量字符串,即内存不再动态管理,因此将它传递给realloc 调用未定义的行为.
  • 您的结果字符串永远不会大于原始字符串,因此您可以从分配len +1 字符开始。在循环结束时,您可以决定重新分配()它。
  • 其他问题包括每次迭代都重新计算strlen(string),即使它是恒定的。照原样,您甚至不需要知道长度,因为您可以迭代直到遇到 NUL 终止符。同样重复的strcat 变得越来越无效,因为它每次都需要找到字符串的结尾。而是跟踪结束位置并附加到那里。 (注意这些都是比较长远的事情要考虑和一般的思考方式,先了解一下内存分配、指针和sizeof是怎么工作的,还有数组和指针的区别。)

标签: c string malloc realloc


【解决方案1】:

realloc 需要分配的字节数。 size 对于添加到 res 的每个字符都会递增。 size + 2 用于提供要添加的当前字符和终止零。
检查realloc 的返回。 NULL 表示失败。如果realloc 失败,使用tmp 允许返回res

char * notX(char * string){

   char* res = NULL;//so realloc will work on first call
   char* tmp = NULL;//temp pointer during realloc
   size_t size = 0;
   size_t index = 0;

    while ( string[index]) {//not the terminating zero
        if ( string[index] != 'X') {
            if ( NULL == ( tmp = realloc(res, size + 2))) {//+ 2 for character and zero
                fprintf ( stderr, "realloc problem\n");
                if ( res) {//not NULL
                    res[size] = 0;//terminate
                }
                return res;
            }
            res = tmp;//assign realloc pointer back to res
            res[size] = string[index];
            ++size;
        }
        ++index;//next character
    }
    if ( res) {//not NULL
        res[size] = 0;//terminate
    }
   return res;
}

【讨论】:

    【解决方案2】:

    此代码中的 2 个主要错误:

    • ma​​llocrealloc 函数带有调用 sizeof(char*) 的参数。在这种情况下,sizeof(char*) 的结果是指针的大小,而不是字符的大小,因此您必须在 sizeof 函数中将 char* 替换为 char

    • res = ""; 不正确。您主要有内存泄漏,因为您丢失了指向 malloc 函数中刚刚分配的内存的指针,次要但同样重要的是,当在 res 初始化为空字符串(或更好的常量字符串)上调用 realloc 函数时,您有未定义的行为,在上述初始化之后,内存不再是动态管理的。为了替代这个初始化,我认为将 memset 设置为 0 是最好的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多