Программа на C, которая хранит неизвестное количество строк неизвестных размеров из блока пользовательской кучи в 00558068, измененного в 00558096, ранее запрошенного размера 26

#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.
}