Указатель C на указатель перезаписывает последний сохраненный - PullRequest
0 голосов
/ 04 июля 2018

Что я хочу сделать, это взять строку, сохранить ее в массив строк, а затем изменить каждую копию на основе индекса.

Я редактировал вопрос и код, он был грязным и неясным. Поскольку вопрос почти такой же (я думаю, что теперь он более точный), я подумал, что могу полностью отредактировать его здесь, не создавая новый вопрос, но дайте мне знать, если мне придется поступить иначе.

ПРОБЛЕМА (РЕДАКТИРОВАТЬ) : после прочтения данного ответа, создания MVCE и чтения this и некоторых советов по отладке, я думаю, что я путаюсь с указателями и strcpy ... Почему следующий код (отредактированный как MVCE) дает этот вывод?

abc
x 
x
y

Он компилируется и не дает ошибок отладки, но я хочу, чтобы код изменил первый символ строки в line_ret на "x", если index == 0, и на "y", если index == 1. Я читаю здесь невозможно изменить один символ в том, на что указывает указатель, но что если я не знаю, сколько раз мне нужно копировать line_read в line_ret, таким образом, не знаю максимума размер индекса для объявления массива line_ret?

Код (РЕДАКТИРОВАТЬ) :

#include<string.h>
#include<stdio.h>
#include<stdlib.h>

size_t len = 10;

int main(void){
    char *line_read = malloc(5);
    strcpy(line_read, "abc");
    char **line_ret = malloc(5 * sizeof(char*));
    int index = 0;

    while(index < 2){
        line_ret[index] = realloc(line_ret, 1*len);

        memcpy(&line_ret[index], &line_read, len);
        printf("%s\n", line_ret[index]);

        if(index == 0){
            strcpy(&line_ret[index][0], "x");
        } else if(index == 1){
            strcpy(&line_ret[index][0], "y");
        }
        printf("%s\n", line_ret[index]);

        index++;
    }

    free(line_read);
    free(line_ret);

    return 0;
}

1 Ответ

0 голосов
/ 04 июля 2018

Если вы копируете адреса (хранящиеся в указателях) в несколько записей в массиве, но все они указывают на один и тот же фрагмент памяти (т. Е. Адреса одинаковы), то использование разных записей в этом массиве всегда приведет к одному и тому же часть памяти перезаписывается.

Отладка путем сравнения / распечатки адресов, которые вы храните в разных записях вашего массива. Ошибка в том, что две записи массива содержат один и тот же адрес.

Чтобы исправить, убедитесь, что записи в массиве получают разные адреса, т. Е. Ссылаются на отдельные фрагменты памяти с ошибками.
Это означает, что каждый раз, когда вы изменяете индекс, используемый для доступа к вашему массиву, вам также необходимо выделять новый фрагмент памяти для использования вместе с этой другой записью массива.

...