Перейти к содержанию
    

Двумерный массив строк в C

Здравствуйте.

 

Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

 

static char *MyArray[255][8];

void MyFunc()
{
     char *buffer;
     buffer = calloc(1, 51);
     int x, y;
     /*Здесь есть некоторый код, в котором происходит присваивание переменным x, y, buffer*/
     MyArray[x][y] = buffer;
     free(buffer);
}

 

Так вот. После того, как я очищаю буфер, значение MyArray[x][y] превращается в мусор. Как бы мне сохранить значение переменной MyArray при выходе из функции?

Изменено пользователем Freeze Anti

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...
     MyArray[x][y] = buffer;
...

Так вот. После того, как я очищаю буфер, значение MyArray[x][y] превращается в мусор. Как бы мне сохранить значение переменной MyArray при выходе из функции?

Все правильно, это же указатели!

 

strcpy(MyArray[x][y], buffer)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как бы мне сохранить значение переменной MyArray при выходе из функции?

Выделить память где-нибудь вне MyFunc, или просто объявить

static char MyArray[255][8];

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

Так вот. После того, как я очищаю буфер, значение MyArray[x][y] превращается в мусор. Как бы мне сохранить значение переменной MyArray при выходе из функции?

 

Убрать статик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

компилирую в Dev-C++ (компилятор - gcc)

 

strcpy вызывает ошибку доступа к памяти во время исполнения программы

 

static char MyArray[255][8] - это тип char**, а я все же объявляю char***,

 

кстати. еще попробовал создать дополнительную переменную char buf[51]

после этого попытался приравнять buf = buffer компилятор у меня выдал incompatible types in assignment

 

Пытался также просто тупо убрать static - не помогает... к сожалению, не увидел то, что удалили

 

разобрался

 

я перед strcpy не выделял память для MyArray

 

вот так работает

 

static char *MyArray[255][8];

void MyFunc()
{
     char *buffer;
     buffer = calloc(1, 51);
     int x, y;
     /*Здесь есть некоторый код, в котором происходит присваивание переменным x, y, buffer*/
     MyArray[x][y] = calloc(1, sizeof(buffer));
     strcpy(MyArray[x][y], buffer);
     free(buffer);
}

 

всем спасибо за оказанную помощь

Изменено пользователем Freeze Anti

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Осталось выяснить, зачем вообще нужны пляски с calloc, и memcpy, если статически выделенная память уже имеется (если речь действительно идет о массиве строк, а не УКАЗАТЕЛЕЙ на них). В чем заключается "работа" написанного выше я не понял :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

 

нельзя вызывать free(buffer).

 

У вас есть двухмерный аррей пойнтеров на стринги, сами стринги вы правильно аллокируете - calloc,

освобождать будете в другом месте.

При освобождении проверяйте на NULL - если не NULL - free

 

кстати, можно пользовать strdup() вместо calloc() i strcpy()

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:bb-offtopic:

"У вас есть двухмерный аррей пойнтеров на стринги, сами стринги вы правильно аллокируете - " -

Задорнов отдыхает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет - задать этот вопрос в програмистком форуме (на vingrad например). Из 4х советов, озвученных здесь - 3 неправильные (или провокационные, уж не знаю).

Ваше последнее решение тоже неверное.

 

     char *buffer;
     buffer = calloc(1, 51); << Нафига здесь динамическая память?
     int x, y;
     /*Здесь есть некоторый код, в котором происходит присваивание переменным x, y, buffer*/
     MyArray[x][y] = calloc(1, sizeof(buffer)); << Выделили буфер, размером в 1 указатель, а нужно - в длинну строки + 1
     strcpy(MyArray[x][y], buffer); << Зафигачили строку в выделенную память и за ее границы, заодно разрушили всю кучу динамической памяти
     free(buffer);

Изменено пользователем XVR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет - задать этот вопрос ....
Совет не верный - правильный совет - прежде всего сформулировать вопрос хоть как-то, поскольку

Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения.
Мало коррелирует с тем, что автор пытался написать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"двухмерный аррей пойнтеров на стринги" читать как "двухмерный массив указателей на строки".

А в остальном согласен с мнением A. Fig Lee.

 

Значение MyArray[x][y] вовсе не превращается в мусор, там находится указатель на память, выделенную вызовом calloc(1, 51).

А вот после free(buffer) эта память освобождается и при последующих вызовах calloc() может быть выделена уже под другую строку. Просто не нужно освобождать память под строку, до тех пор пока она нужна. А как перестала быть нужной - можно и освободить:

free( MyArray[x][y] );

MyArray[x][y] = NULL;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет - задать этот вопрос в програмистком форуме (на vingrad например).

 

мы и сюда ходим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мы и сюда ходим.
Точно, тогда понятно откуда пришел единственный правильный ответ :cheers:

С мнением zltigo полностью согласен - не понятно, чего аффтор хотел. Понятно только то, что получил он не то, что хотел (что бы это не было :rolleyes: )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

XVR не прав - неправильных ответов здесь гораздо больше.

 

Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

MyArray - это не массив строк, а массив указателей, он может указывать на любую строку, но сам он ее не содержит. Строкой MyArray[x][y] = buffer; ты указываешь на buffer, но следом этот буфер удаляешь. Поэтому указатель в MyArray после этого указывает в пустоту.

Потом, тебе не мешало бы понять что такое строка в Си, тогда тебе станет ясно, что массивов строк, а тем более двумерных, вообще говоря не бывает. Строка это одномерный массив char-ов заполненный символами и оканчивающийся нулем. Поскольку строки могут быть разной длины, то массив из них не создашь. Поэтому обычно имеют дело с указателями на строки - создается переменная типа char* или массив как у тебя MyArray и отдельно создаются строки, выделяя для каджой из них память нужной длины. После этого нужному элементу массива присваивается значение адреса выделенной строки и с ней работают. Удалять же ее нужно только по окончании работы, а не как у тебя.

 

 

XVR не прав - неправильных ответов здесь гораздо больше.

Кстати, это одна из причин почему надо ликвидировать раздел "Для начинающих" - его посещают только начинающие, поэтому дать правильный ответ некому.

 

Совет - задать этот вопрос в програмистком форуме (на vingrad например).

Фигасе форум. Программисты не смогли даже для себя нормальный форум создать, о чем там с ними можно говорить?

А про rsdn.ru вы когда-нибудь слышали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...