首页 > 解决方案 > realloc():为字符串数组重新分配内存时出现无效的下一个大小错误

问题描述

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

// 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而我无权访问。我正在使用strnlenandstrcpy代替。我不确定这是否是导致问题的原因。然而,这是书中的逐字代码:

// 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 行后收到该错误。

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

标签: arrayscpointers

解决方案


感谢 user3121023 的建议,我通过更改此行来解决它:

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

对此:

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

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


推荐阅读