реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Двумерный массив строк в C
Freeze Anti
сообщение Feb 10 2009, 11:29
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613



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

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

Код
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 - Feb 10 2009, 11:35


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
amw
сообщение Feb 10 2009, 11:59
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(Freeze Anti @ Feb 10 2009, 13:29) *
Код
...
     MyArray[x][y] = buffer;
...

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

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

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


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 10 2009, 12:01
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Freeze Anti @ Feb 10 2009, 14:29) *
Как бы мне сохранить значение переменной MyArray при выходе из функции?

Выделить память где-нибудь вне MyFunc, или просто объявить
Код
static char MyArray[255][8];
Go to the top of the page
 
+Quote Post
SergeyTT
сообщение Feb 10 2009, 12:33
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 3-07-06
Из: Харьков
Пользователь №: 18 533



Цитата(Freeze Anti @ Feb 10 2009, 13:29) *
Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

Цитата(Freeze Anti @ Feb 10 2009, 13:29) *
Так вот. После того, как я очищаю буфер, значение MyArray[x][y] превращается в мусор. Как бы мне сохранить значение переменной MyArray при выходе из функции?


Убрать статик.
Причина редактирования: Нарушение п.3.4 Правил форума
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Feb 10 2009, 13:07
Сообщение #5


Частый гость
**

Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613



компилирую в 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 - Feb 10 2009, 12:47


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 10 2009, 13:26
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Feb 10 2009, 16:54
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(Freeze Anti @ Feb 10 2009, 06:29) *
Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.


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

У вас есть двухмерный аррей пойнтеров на стринги, сами стринги вы правильно аллокируете - calloc,
освобождать будете в другом месте.
При освобождении проверяйте на NULL - если не NULL - free

кстати, можно пользовать strdup() вместо calloc() i strcpy()
Причина редактирования: Удалено излишнее цитирование.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
AnV22
сообщение Feb 11 2009, 07:16
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 18-06-07
Из: Челябинск
Пользователь №: 28 529



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


--------------------
- Своя программа жизни -
Go to the top of the page
 
+Quote Post
XVR
сообщение Feb 11 2009, 07:50
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Совет - задать этот вопрос в програмистком форуме (на 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 - Feb 11 2009, 07:51
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 11 2009, 07:58
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(XVR @ Feb 11 2009, 10:50) *
Совет - задать этот вопрос ....
Совет не верный - правильный совет - прежде всего сформулировать вопрос хоть как-то, поскольку
Цитата
Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения.
Мало коррелирует с тем, что автор пытался написать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SSerge
сообщение Feb 11 2009, 09:27
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



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

Значение MyArray[x][y] вовсе не превращается в мусор, там находится указатель на память, выделенную вызовом calloc(1, 51).
А вот после free(buffer) эта память освобождается и при последующих вызовах calloc() может быть выделена уже под другую строку. Просто не нужно освобождать память под строку, до тех пор пока она нужна. А как перестала быть нужной - можно и освободить:
free( MyArray[x][y] );
MyArray[x][y] = NULL;


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Feb 11 2009, 15:03
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(XVR @ Feb 11 2009, 02:50) *
Совет - задать этот вопрос в програмистком форуме (на vingrad например).


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


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
XVR
сообщение Feb 12 2009, 08:35
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(A. Fig Lee @ Feb 11 2009, 18:03) *
мы и сюда ходим.
Точно, тогда понятно откуда пришел единственный правильный ответ cheers.gif
С мнением zltigo полностью согласен - не понятно, чего аффтор хотел. Понятно только то, что получил он не то, что хотел (что бы это не было rolleyes.gif )
Go to the top of the page
 
+Quote Post
777777
сообщение Feb 13 2009, 06:49
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



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

Цитата(Freeze Anti @ Feb 10 2009, 14:29) *
Суть моего вопроса такова. Мне необходимо создать двумерный массив, состоящий из строк. Потом мне нужно в отдельной функции по необходимости добавлять туда значения. Делаю это так.

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


Цитата(777777 @ Feb 13 2009, 09:43) *
XVR не прав - неправильных ответов здесь гораздо больше.

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

Цитата(XVR @ Feb 11 2009, 10:50) *
Совет - задать этот вопрос в програмистком форуме (на vingrad например).

Фигасе форум. Программисты не смогли даже для себя нормальный форум создать, о чем там с ними можно говорить?
А про rsdn.ru вы когда-нибудь слышали?
Причина редактирования: Уменьшение размера цитаты.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 15:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01486 секунд с 7
ELECTRONIX ©2004-2016