Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Прерывание указателя strcpy char

Автор вопроса: Emil GrigoreОтветов: 2

У меня есть этот код:

     char **arr;
     char* line=NULL;
     int i=0;
     size_t len=0;
     ssize_t read1;

     fp=fopen("list.txt","r");
     if(fp==NULL)
         exit(EXIT_FAILURE);

     while((read1=getline(&line,&len,fp))!=-1)
         i++;
     fclose(fp);

     fp=fopen("list.txt","r");
     if(fp==NULL)
         exit(EXIT_FAILURE);

     arr=(char**)malloc(i*sizeof(char*)); // i is a variable i use to know the number of lines
     i=0;

     while((read1=getline(&line,&len,fp))!=-1)
     {
         line[strlen(line)]='\0';
         arr[i]=(char*)malloc(strlen(line)+1);
         strcpy(arr[i],line);
         i++;
     }

При попытке strcpy программа вылетает. Проблема в malloc? Я очень уверен, что i достаточно большой. И line это char* и сначала NULL.

РЕДАКТИРОВАТЬ: я забыл, что эта программа находится в Qt.

  • Вам не нужно приводить возвращаемое значение malloc() в программе C. Carl Norum 24.01.2013
  • i - это переменная, которую я использую для определения количества строк. Тогда почему она называется i, а не numberOfLines/linesNumber? LihO 24.01.2013
  • Как определяется line? И каково определение/значение len? Evan Teran 24.01.2013
  • Откуда вы знаете, что начальный i достаточно велик? Oliver Charlesworth 24.01.2013
  • @Oil: действительно, хороший улов, @Emil, каково значение i перед этим кодом? Evan Teran 24.01.2013
  • line[strlen(line)]='\0' ничего не значит. Theodoros Chatzigiannakis 24.01.2013

c++qtmallocstrcpy

Ответы

Ответ 1 · рейтинг 3 · Evan Teran

Есть пара проблем с кодом, я прокомментирую то, что, по моему мнению, должно работать...:

 // I **assume** that these are the definitions for these variables
 // based on your comments
 size_t len = 0;
 char *line = NULL;
 ssize_t read1;

 // I **assume** that i has a reasonable value here, but this is not good to assume,
 // what if the file is a line longer tomorrow? I hope that you calculate the number
 // of lines somehow, that would be "less bad"
 int i = 10; // 10 lines in the file, who knows ?!?
 char **arr;

 // don't bother casting...
 arr = malloc(i * sizeof(char*));
 i=0;

 while((read1 = getline(&line, &len, fp)) != -1) {

     // THIS LINE DOES NOTHING, so we can just remove it
     // line[strlen(line)]='\0';

     arr[i] = line; // since you asked getline to allocate a buffer for
                    // you (line was NULL), you can just store the buffer directly
                    // it's YOURS
     i++;

     // THIS IS THE BIG ONE:
     // it is needed because otherwise the NEXT call to getline will
     // reuse the same buffer, which may not be big enough
     line = NULL;
 }

Кроме того, позже для очистки вы должны сделать что-то вроде этого:

int j;
for(j = 0; j < i; ++j) {
    free(arr[j]);
}
free(arr);
arr = NULL; // not necessary, but good practice to avoid double frees and such

Ответ 2 · рейтинг 2 · qPCR4vir

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

 arr=(char**)malloc(i_ori*sizeof(char*));//i_ori is a variable i use to know the number of lines
 i=0;

 while((read1=getline(&line,&len,fp))!=-1 && i<i_ori)

Кроме того, вы никогда не проверяете, возвращает ли malloc NULL !! См. https://stackoverflow.com/a/2280342/1458030.

@Emil Grigore: Когда я пытаюсь использовать strcpy, программа падает. Проблема с malloc? Я очень уверен, что я достаточно большой.

Да! вам нужно проверить на NULL.

Если вы используете C++ и Qt, почему бы не использовать контейнеры и потоки?

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы