【问题标题】:realloc(): invalid next size error when reallocating memory for an array of stringsrealloc():为字符串数组重新分配内存时出现无效的下一个大小错误
【发布时间】:2021-10-20 10:24:54
【问题描述】:

我一直在阅读Beginning C, Fifth Edition,目前正在阅读关于指针的第 7 章。我尝试运行本章中给出的示例,但是当数组超过 6 个元素的容量时,我遇到了 realloc(): invalid next size 错误。这是从书中大部分复制和粘贴的代码:

// Program 7.14 Using array notation with pointers to sort strings

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

#define BUF_LEN 100                                // Length of input buffer
#define COUNT         5                            // Initial number of strings

int main(void)
{
  char buf[BUF_LEN];                               // Input buffer
  size_t str_count = 0;                            // Current string count
  size_t capacity = COUNT;                         // Current maximum number of strings
  char **pS = calloc(capacity, sizeof(char*));     // Pointers to strings
  char** psTemp = NULL;                            // Temporary pointer to pointer to char
  char* pTemp = NULL;                              // Temporary pointer to char
  size_t str_len = 0;                              // Length of a string
  bool sorted = false;                             // Indicated when strings are sorted
  printf("Enter strings to be sorted, one per line. Press Enter to end:\n");

  // Read in all the strings
  char *ptr = NULL;
  while(true)
  {
    ptr = fgets(buf, BUF_LEN, stdin);
    if(!ptr) // Check for read error
    {
      printf("Error reading string.\n");
      free(pS);
      pS = NULL;
      return 1;
    }

    if(*ptr == '\n') break;             // Empty line check

    if(str_count == capacity)
    {
      capacity += capacity/4;           // Increase capacity by 25%

      if(!(psTemp = realloc(pS, capacity))) return 1;

      pS = psTemp;
    }
    str_len = strnlen(buf, BUF_LEN) + 1;
    if(!(pS[str_count] = malloc(str_len))) return 2;
    strcpy(pS[str_count++], buf);
  }

  // Sort the strings in ascending order
  while(!sorted)
  {
    sorted = true;
    for(size_t i = 0 ; i < str_count - 1 ; ++i)
    {
      if(strcmp(pS[i], pS[i + 1]) > 0)
      {
        sorted = false;                 // We were out of order so. . .
        pTemp= pS[i];                   // swap pointers pS[i]. . .
        pS[i] = pS[i + 1];              // and. . .
        pS[i + 1] = pTemp;              // pS[i + 1]
      }
    }
  }

  // Output the sorted strings
  printf("Your input sorted in ascending sequence is:\n\n");
  for(size_t i = 0 ; i < str_count ; ++i)
  {
    printf("%s", pS[i]);
    free(pS[i]);                        // Release memory for the word
    pS[i] = NULL;                       // Reset the pointer
  }
  free(pS);                             // Release the memory for pointers
  pS = NULL;                            // Reset the pointer
  return 0;
}

错误发生在这一行:

if(!(psTemp = realloc(pS, capacity))) return 1;

另外,我说代码是“大部分”复制的,因为书中的代码使用了我无法访问的 C11 函数,例如 strnlen_sstrcpy_s。我改用strnlenstrcpy。我不确定这是否是导致问题的原因。然而,这是书中的逐字代码:

// Program 7.14 Using array notation with pointers to sort strings
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define BUF_LEN 100                                // Length of input buffer
#define COUNT         5                            // Initial number of strings

int main(void)
{
  char buf[BUF_LEN];                               // Input buffer
  size_t str_count = 0;                            // Current string count
  size_t capacity = COUNT;                         // Current maximum number of strings
  char **pS = calloc(capacity, sizeof(char*));     // Pointers to strings
  char** psTemp = NULL;                            // Temporary pointer to pointer to char
  char* pTemp = NULL;                              // Temporary pointer to char
  size_t str_len = 0;                              // Length of a string
  bool sorted = false;                             // Indicated when strings are sorted
  printf("Enter strings to be sorted, one per line. Press Enter to end:\n");

  // Read in all the strings
  char *ptr = NULL;
  while(true)
  {
    ptr = fgets(buf, BUF_LEN, stdin);
    if(!ptr) // Check for read error
    {
      printf("Error reading string.\n");
      free(pS);
      pS = NULL;
      return 1;
    }

    if(*ptr == '\n') break;             // Empty line check

    if(str_count == capacity)
    {
      capacity += capacity/4;           // Increase capacity by 25%

      if(!(psTemp = realloc(pS, capacity))) return 1;

      pS = psTemp;
    }
    str_len = strnlen_s(buf, BUF_LEN) + 1;
    if(!(pS[str_count] = malloc(str_len))) return 2;
    strcpy_s(pS[str_count++], str_len, buf);
  }

  // Sort the strings in ascending order
  while(!sorted)
  {
    sorted = true;
    for(size_t i = 0 ; i < str_count - 1 ; ++i)
    {
      if(strcmp(pS[i], pS[i + 1]) > 0)
      {
        sorted = false;                 // We were out of order so. . .
        pTemp= pS[i];                   // swap pointers pS[i]. . .
        pS[i] = pS[i + 1];              // and. . .
        pS[i + 1] = pTemp;              // pS[i + 1]
      }
    }
  }

  // Output the sorted strings
  printf("Your input sorted in ascending sequence is:\n\n");
  for(size_t i = 0 ; i < str_count ; ++i)
  {
    printf("%s", pS[i]);
    free(pS[i]);                        // Release memory for the word
    pS[i] = NULL;                       // Reset the pointer
  }
  free(pS);                             // Release the memory for pointers
  pS = NULL;                            // Reset the pointer
  return 0;
}

我在 StackOverflow 和其他地方查找了很多帖子来帮助我找出问题所在,但我无法弄清楚。我还使用 gdb 和 valgrind 来尝试诊断问题,但我也无法从这些工具中收集到太多信息。不过,我对它们非常缺乏经验,尤其是 valgrind。

我认为我缺少一些小东西。下面是一个使用书中输入的运行程序的示例:

Enter strings to be sorted, one per line. Press Enter to end:
Many a mickle makes a muckle.
A fool and your money are soon partners.
Every dog has his day.
Do unto others before they do it to you.
A nod is as good as a wink to a blind horse.
The bigger they are, the harder they hit.
Least said, soonest mended.
realloc(): invalid next size
signal: aborted (core dumped)

无论输入是什么,我都会在 7 行后得到该错误。

对此的任何帮助将不胜感激。提前致谢!

【问题讨论】:

  • 当您在调用realloc 之前超出分配的内存范围时,通常会发生此类错误。例如,如果您在 realloc 调用中分配了少量内存(要重新分配的大小是要分配的 bytes 数量,而不是“元素”的数量)。
  • 我很确定您没有逐字复制示例。你应该先这样做。为什么您无法访问 C11 功能?是什么阻止您使用与 C11 不兼容的非古老编译器?
  • 感谢大家的 cmets,@user3121023 的解决方案为我解决了这个问题。我应该用解决方案回答我自己的问题吗?
  • @SergeyA 我在 Replit 上使用在线编译器来运行代码,我猜那里的编译器没有 C11 函数。我还编辑了问题,以包括从书中逐字提取的代码。
  • @amehdi96 您可以使用任何其他支持 C11 的在线编译器,例如 coliru.stacked-crooked.com

标签: arrays c pointers


【解决方案1】:

感谢user3121023的建议,我通过更改这一行解决了它:

if(!(psTemp = realloc(pS, capacity))) return 1;

到这里:

if(!(psTemp = realloc(pS, capacity * sizeof(*pS)))) return 1;

这样做的原因是因为我必须分配字节的数量,而不是元素的数量。我不知道为什么这本书有错误,但我认为它是一个较早的版本,所以它可能会在以后的版本中修复。

【讨论】:

    猜你喜欢
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    相关资源
    最近更新 更多