FILE *file;
file = fopen(argv[1], "r");
char *match = argv[2];
if (file == NULL) {
printf("File does not exist\n");
return EXIT_FAILURE;
}
int numWords = 0, memLimit = 20;
char** words = (char**) calloc(memLimit, sizeof(char));
printf("Allocated initial array of 20 character pointers.\n");
char string[20];
while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) != EOF) {
words[numWords] = malloc(strlen(string) + 1 * sizeof(char));
strcpy(words[numWords], string);
printf("Words: %s\n", words[numWords]);
numWords++; /*keep track of indexes, to realloc*/
if (numWords == memLimit) {
memLimit = 2 * memLimit;
words = (char**) realloc(words, memLimit * sizeof(char*)); /*Fails here*/
printf("Reallocated array of %d character pointers.\n", memLimit);
}
}
代码应该打开并读取包含带标点符号,空格等单词的文件并存储在一个字符串中,但是在20次尝试之后它会抛出一个错误,我似乎无法让realloc()在这里工作,我期待成为问题。该数组动态分配20个char指针,当达到限制时,它应该重新分配为double。我怎么能绕过这个?
答案 0 :(得分:3)
两个音符。首先,您不应该转换calloc / malloc / realloc的返回值。有关详细信息,请参阅this。
其次,正如其他人在评论中指出的那样,第一个calloc语句使用的是sizeof(char)
而不是sizeof(char*)
。
答案 1 :(得分:2)
words
是指向指针的指针。想法是分配一个指针数组
以下是错误的,因为它分配了memLimit
个字符而不是memLimit
个字符
这是主要问题
char** words = (char**) calloc(memLimit, sizeof(char)); // bad
因此,请使用简单的习惯用法:分配memLimit
个words
点的char** words = calloc(memLimit, sizeof *words);
组。它更容易编写,阅读和维护。
while (scanf() != EOF)
避免scanf()
洞。回想一下,EOF
家族可以得到各种结果。它返回成功扫描的字段数或// while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) != EOF) {
while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) == 1) {
。这通常是至少3个选项中的1个。因此,不要测试您不想要的一个结果,测试您想要的的结果。
int d;
while (fscanf(file, "%d", &d) == 1) {
以上示例可能并非每次返回0,但下面的内容很容易。
"%s"
@Enzo Ferber正确建议使用char string[20];
while (fscanf(file, "%19s", string) == 1) {
。进一步建议遵循上述习语,并将输入宽度限制为小于缓冲区大小的1。
// better to use `size_t` rather than `int `for array sizes.
size_t newLimit = 2u * memLimit;
char** newptr = realloc(words, newLimit * sizeof *newptr);
if (newptr == NULL) {
puts("Out-of-memory");
// Code still can use old `words` pointer of size `memLimit * sizeof *words`
return -1;
}
memLimit = newLimit;
words = newptr;
}
建议检查分配结果的习惯。
...
var html = "<div style='font-size: 2em; text-align: center;'>Some text here." +
"<br /><br />" +
"<ul>" +
"<li>A bunch of text here</li>" +
"<li>A bunch more text here</li>" +
"</ul>" +
"</div>";
iframeBody.innerHTML = html;
...
答案 2 :(得分:1)
sizeof
错了。它应该是sizeof(char*)
scanf()
格式字符串。 %s
做得很好。以下代码适用于我(每行打印一个字):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *file;
file = fopen(argv[1], "r");
char *match = argv[2];
if (file == NULL) {
printf("File does not exist\n");
return EXIT_FAILURE;
}
int numWords = 0, memLimit = 20;
char **words = calloc(memLimit, sizeof(char*));
printf("Allocated initial array of 20 character pointers.\n");
char string[20];
while (fscanf(file, "%s", string) != EOF) {
words[numWords] =
malloc(strlen(string) + 1 * sizeof(char));
strcpy(words[numWords], string);
printf("Words: %s\n", words[numWords]);
numWords++; /*keep track of indexes, to realloc */
if (numWords == memLimit) {
memLimit = 2 * memLimit;
words = realloc(words, memLimit * sizeof(char *));
printf
("Reallocated array of %d character pointers.\n",
memLimit);
}
}
}
使用./realloc realloc.c
希望它有所帮助。
答案 3 :(得分:1)
你的第一个分配是问题。你分配20个字符并将它们视为20个字符指针。你超出了分配的缓冲区并破坏了你的记忆。
第二次分配失败,因为堆已损坏。