【发布时间】: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_s 和 strcpy_s。我改用strnlen 和strcpy。我不确定这是否是导致问题的原因。然而,这是书中的逐字代码:
// 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