#c #string #heap-memory #block #realloc
#c #строка #куча-память #блок #перераспределение
Вопрос:
Я пытаюсь написать программу на C, которая принимает неизвестное количество строк (каждая неизвестного размера) от пользователя в качестве входных данных и сохраняет их, а затем печатает их, когда пользователь заканчивает вводить строки.
Сначала я использую указатель, который указывает на символьные указатели (строки char **) и выделяю для него блок памяти размером 1 char * с помощью malloc. Затем я выделяю 1 блок размером с символ для указателя, на который указывает strings ( (strings) ), также с помощью malloc. Оттуда я беру строку, введенную пользователем, используя определяемую пользователем функцию с именем get_String(), и помещаю ее в указатель char, на который указывает строка char *. Затем я использую цикл for, чтобы продолжить выделение дополнительного символа * памяти для строк char ** и 1 символа памяти для нового указателя.
Тем не менее, я продолжаю испытывать ошибку на 2-й итерации цикла for, в строке strings = (char **) realloc (строки, индекс 1); и я получаю сообщение об ошибке: блок кучи в 00558068 изменен в 00558096 с превышением запрошенного размера 26. Кажется, что я записываю за пределы выделенной памяти в строки char **, но я не знаю, где и как я это делаю.
Вот весь мой код:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
void get_strings( char* strings); // function to take in a string of an unknown size
int main( void )
{
char** strings;
int index, count;
(strings) = (char**) malloc( sizeof(char*)); // this is the pointer that holds the addresses of all the strings
*strings = (char*) malloc( sizeof(char)); // the address of the first string
printf( "Enter a list of stringss. Quit by pressing enter without entering anythingn" );
get_strings( *strings );
for( index = 1; strlen(*(strings index-1))!=1; index ) // stores strings from the user until they enter a blank line which is detected when string length is 1 for the n
{
strings = (char**) realloc (strings, index 1); // adds an extra character pointer for another string
*(strings index) = (char*) malloc(sizeof(char)); // allocates memory to the new character pointer
get_strings( *(strings index) ); // stores the string from the user
}
printf( "You entered:n" );
for( count = 0; strlen(*(strings count)) != 1; count ) //prints every string entered by the user except for the terminating blank line
{
printf( "%s", *(strings count ) );
free( *(strings count ));
}
free( strings );
system( "PAUSE" );
return 0;
}
void get_strings( char* strings )
{
fgets( strings, 1, stdin );
while( strings[ strlen( strings ) - 1 ] != 'n' )
{
strings = (char*) realloc( strings, strlen(strings) 2 );
fgets( strings strlen(strings), 2, stdin );
}
}
Как указывалось ранее, блок кучи возникает на второй итерации цикла for при выполнении строки: strings = (char**) realloc (строки, индекс 1);
for( index = 1; strlen(*(strings index-1))!=1; index ) // stores strings from the user until they enter a blank line which is detected when string length is 1 for the n
{
strings = (char**) realloc (strings, index 1); // error occurs here
*(strings index) = (char*) malloc(sizeof(char)); // allocates memory to the new character pointer
Я был бы очень признателен, если бы кто-нибудь мог объяснить мне причину этой ошибки и указания по ее исправлению. Спасибо.
Комментарии:
1. Вам следует выполнить некоторую отладку, чтобы выяснить, почему.
2. Полезность этого:
*(strings index) = (char*) malloc(sizeof(char));
весьма сомнительна. Выget_string
должны вернуть динамический адрес полученной строки, и указанный адрес должен быть назначен в вашем массиве указателей (индексация которого также весьма сомнительна). Желаю удачи.3. Вы смотрели на C ? Такие классы, как std::vector и std::string, делают написание такого кода почти тривиальным.
4. 1)
fgets( strings, 1, stdin );
: Она по существу недействительна, поскольку не сохраняет входные данные.5. 2)
strings = (char*) realloc( strings, strlen(strings) 2 );
: Это по существу недопустимо, потому что это не отражено в вызывающем устройстве.
Ответ №1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *get_strings(void);
int main( void ){
char **strings = NULL;
char *string;
int index, count;
printf( "Enter a list of stringss. Quit by pressing enter without entering anythingn" );
for(index = 0; string = get_strings(); index){
strings = (char**) realloc (strings, (index 1)*sizeof(*strings));
strings[index] = string;
}
printf( "You entered:n" );
for( count = 0; count < index; count ){
printf("%sn", strings[count]);
free( strings[count] );
}
free( strings );
system( "PAUSE" );
return 0;
}
char *get_strings(void){
char *string = NULL;//or calloc(1,sizeof(char)) for return "" (test by caller: *string == '')
int ch;
size_t len = 0;
while(EOF != (ch=fgetc(stdin)) amp;amp; ch != 'n' ) {
string = (char*)realloc( string, len 2);//To realloc to each character is inefficient
string[len ] = ch;
}
if(string)
string[len] = '';
return string;//The value is NULL when there is no input substantial.
}