Перераспределение не работает в цикле while
Мне нужна помощь с моим заданием на C. Задача состоит в том, чтобы написать программу, которая принимает строковый ввод неизвестной длины. Также мне нужно разделять слова, поэтому я использую char**
. Программа перестает принимать ввод, когда появляется специальное слово. Вы можете увидеть мой код ниже:
char **words=NULL;
maxWords=1;
numberOfWords=0;
words=calloc(maxWords,sizeof(char **));
input=malloc(max*sizeof(char *));
words[numberOfWords]=calloc(max,sizeof(char*));
while(stopValue){
while((c=getchar())!='n' && c!=' ' && c!=EOF){
input[i++]=c;
if(i==currentSize){
currentSize=i+max;
input=realloc(input,currentSize);
words[numberOfWords]=realloc(words[numberOfWords],currentSize);
}
}
input[i]='';
if(strcmp(input,terminator)==0){
break;
}
strcpy( words[numberOfWords],input);
numberOfWords++;
maxWords++;
words=realloc(words,maxWords);
words[numberOfWords]=calloc(max,sizeof(char*));
currentSize=max;
i=0;
input=realloc(input,max);
}
Это хорошо работает, когда у меня есть только 2-3 слова ввода. Но он терпит неудачу, когда их становится больше. Я думаю, что проблема заключается в words=realloc(words,maxWords);
этой строке, но я не знаю, что именно.
Какая-нибудь помощь, пожалуйста?
1 ответ:
Вторым аргументом для
calloc()
должен быть размер того, на что указывает указатель, то есть указываемый тип, а не размер самого типа указателя.Например, предположим, что вы хотите выделить место для 10
int
, присвоив результатint *p
, любой из следующих вариантов будет правильным синтаксисом и покажет определенное поведение:int *a = malloc(10 * sizeof(int)); int *b = calloc(10, sizeof(int)); int *c = realloc(NULL, 10*sizeof(int)) int *d = malloc(10 * sizeof *d); int *e = calloc(10, sizeof *e); int *f = realloc(NULL, 10 * sizeof *f);
Указатель на указатель действует не иначе. Если вы хотите выделить последовательность указателей на символ, то синтаксис идентичен применяется:
Обратите внимание, что не только синтаксис, но и фактический код последних трех в обоих приведенных выше списках идентичен , за исключением самого типа указателя (первый-указатель на int, второй-указатель на char). Этот синтаксис использует преимущество того, как операторchar **a = malloc(10 * sizeof(char*)); char **b = calloc(10, sizeof(char*)); char **c = realloc(NULL, 10*sizeof(char*)) char **d = malloc(10 * sizeof *d); char **e = calloc(10, sizeof *e); char **f = realloc(NULL, 10 * sizeof *f);
sizeof
(это не функция или макрос; это оператор) может использоваться против переменной , а не типа .Это говорит, что
words
в вашем коде является указатель на указатель на символ. Я должен быть выделен с использованием аналогичного синтаксиса для правильного определения размера. Любое из следующих действий будет работать правильно:char **words = calloc(maxwords, sizeof(char*)); // right, uses specific type char **words = calloc(maxwords, sizeof *words); // right, gets size from var type
Оба делают одно и то же: выделяют буфер, правильно выровненный и размерный, чтобы вместить
maxwords
Количествоchar*
, именно то, что вы хотели бы для хранения указателей на строки.Эта проблема повторяется снова, когда вы делаете это:
words[numberOfWords] = calloc(max, sizeof(char*)); // wrong
Опять же,
words
являетсяchar**
, поэтомуwords[anything]
являетсяchar*
и, как таковой, должен быть назначен распределение, основанное на размере указываемого типа:char
. Это будет сделано любым из следующих способов:words[numberOfWords] = calloc(max, sizeof(char)); // right, or... words[numberOfWords] = calloc(max, sizeof **words); // right
Хорошо все это сказано, ваше подозрение, что это неправильно:
Это хорошо обосновано. Функцияwords = realloc(words, maxWords);
realloc
принимает в качестве второго параметра число байтов . Вы передаетеcount of pointers
, но не включаете размер каждого указателя в число запрошенных байтов. Используя синтаксис, описанный ранее, это можно сделать как:words = realloc(words, maxWords * sizeof *words);
Или
words = realloc(words, maxWords * sizeof(char*));
Либо будет работать, и теперь включает размер каждого указателя, тем самым вычисляя правильное количество байтов для запроса.
Желаю удачи.