правильное распределение памяти для строк

Поэтому у меня была эта проблема, которую я пытался решить в течение примерно 8 часов … Я отказался от поиска ответа без посторонней помощи. Я пробовал использовать realloc() и malloc() соответственно, поэтому любой вход был бы замечательным!

objective этого нахождения в C состоит в том, чтобы разрешить создание «карты», позже я буду использовать ncurses для создания карты.

вход из файла выглядит следующим образом

 10X16 de4 dw9 ds8 g8,7 m3,4 h6,5 p2,2 6X20 dn5 ds4 W4,3 e2,12 M1,1 10X13 ds3 dw9 10X12 5X4 6x12 

Вот код:

 char *importLevel() { FILE *fPointer; fPointer = fopen("Level", "r"); //Opens text file to read char* rooms[150];// set up for memory allocation char commands[150];// set up for pulling data from read file while (!feof(fPointer)) { fgets(commands,150, fPointer); // this takes each line from the file } *rooms = (char *) malloc(150 * sizeof(char)); // memory allocation for (int i = 0; i < 150; i++) { if (rooms[i] != NULL) { *rooms[i] = commands[i]; // supposed to give rooms the string } } fclose(fPointer);// close file return *rooms; // return pointer } 

Надеюсь, я не так глуп, как сейчас чувствую! Спасибо 🙂

edit: Я так глуп, как я чувствовал себя тогда

Другие указали некоторые изменения, которые вам нужно будет сделать. Итак, посмотрите, что они сказали, и сравните свою версию с приведенной ниже. Это должно помочь.

Вот исправленная версия вашей программы. Я должен был догадываться о некоторых ваших намерениях, основываясь на вашем коде и данных [прошу прощения за бесплатную стильную очистку]:

 #include  #include  #include  #include  #include  char ** importLevel() { FILE *fPointer; char commands[150]; // file line buffer int roomcnt = 0; char *cp; char *bp; char **rooms = NULL; // set up for memory allocation fPointer = fopen("Level", "r"); // Opens text file to read if (fPointer == NULL) { printf("importLevel: unable to open file -- %s\n",strerror(errno)); exit(1); } while (1) { // this takes each line from the file cp = fgets(commands, sizeof(commands), fPointer); if (cp == NULL) break; // setup buffer for strtok bp = commands; // parse all words on line while (1) { // NOTE: the first assumes you want "g8,7" within a room // the second assumes you want "g8,7" as two separate rooms #if 1 cp = strtok(bp," \n"); #else cp = strtok(bp," ,\n"); #endif // strtok wants this on 2nd and subsequent loops for this line bp = NULL; // bug out if no more words on this line if (cp == NULL) break; // increase room list size (allow space for terminator) // NOTE: rooms will be preserved when we return from this function rooms = realloc(rooms,sizeof(char *) * (roomcnt + 2)); // NOTE: cp is pointing to something in our stack frame that // will go away when we return or when we read the next line // so we must preserve it in the heap now cp = strdup(cp); // add the contents of the room rooms[roomcnt] = cp; // advance count of number of rooms ++roomcnt; } } // add terminator to list if (rooms != NULL) rooms[roomcnt] = NULL; fclose(fPointer); // close file return rooms; // return pointer } 

PS Не чувствую себя плохо. Независимо от того, насколько опытен программист, мы все делаем «немые» ошибки. И мы делаем их каждый день. Добро пожаловать в клуб!

Здесь есть немало вещей.

 while (!feof(fPointer)) { fgets(commands,150, fPointer); // this takes each line from the file } 

Это будет перезаписывать данные в commands каждый раз через цикл. Когда петля выйдет, вы будете читать и отбрасывать все данные, кроме последней строки. Вы захотите либо использовать 2-мерный массив, либо, скорее всего, хранить данные в rooms мере их чтения. Второй способ быстрее и использует меньше памяти.

 *rooms = (char *) malloc(150 * sizeof(char)); 

Это похоже на то, что вы пытаетесь создать массив 2-го уровня. Вместо этого вы захотите сделать что-то вроде этого:

 for (int ii = 0; ii < 150; ++ii) rooms[ii] = malloc(150 * sizeof(char)); 

Обратите внимание, что этот malloc не инициализирует память. Итак, ваш чек

 if (rooms[i] != NULL) 

Я собираюсь дать вам неопределенные результаты. Содержимое rooms[i] не определено. Если вы хотите инициализировать массив для всех нhive, попробуйте использовать memset .

Затем:

 *rooms[i] = commands[i]; 

Не собираюсь копировать данные из commands , а копирует только первый символ из commands . Чтобы скопировать всю строку, вы захотите использовать strcpy или strncpy чтобы избежать возможных проблем с переполнением буфера. memcpy также является возможностью скопировать некоторое количество байтов вместо C-строк с нулевым завершением.

Наконец, возrotation *rooms - это ошибка, ожидающая своего появления. Вам лучше будет обслуживать rooms в качестве параметра и выделять на это. См. Allocate memory 2d array в функции C для того, как это сделать.