С указателями вопрос - PullRequest
       7

С указателями вопрос

0 голосов
/ 10 апреля 2011

У меня небольшой концептуальный вопрос об указателях.Это может быть неловко, но мне нужно знать ответ.

Я пытался прочитать строку из файла, используя функцию getline.getline принимает char ** в качестве первого аргумента, и именно там хранится указатель строки.Пожалуйста, смотрите вставленный код ниже и скажите мне разницу между ними.Обратите внимание на объявление и использование указателя readLine.

Второй код дал мне ошибку сегментации, когда он достиг printf ().Я проверил значение в * readLine с помощью gdb (до printf ()), и оно было правильным, но когда оно переходит к printf (), бум SIGSEGV

, этот код работает: FILE * fp;

char *readLine;

readLine=NULL;

int s=0;

while(getline(&readLine,(size_t *)&s,fp) != -1){

    printf("%s\n",readLine);

}

этот код не работает: FILE * fp;

char **readLine;

*readLine=NULL;

int s=0;

while(getline(readLine,(size_t *)&s,fp) != -1){

    printf("%s\n",*readLine);

}

cheers ... rv

Ответы [ 3 ]

2 голосов
/ 10 апреля 2011
(size_t *)&s

Это приведет к аварийному завершению работы 64-разрядной машины с 32-разрядной int с.Решение проблемы такого рода состоит в том, чтобы объявить требуемый тип (size_t s;), но ничего не приводить.В x86-64 это назначает 8 байтов 4-байтовому расположению в стеке, что приводит к повреждению стека.Поскольку перезапись происходит в вызываемой функции, она может перезаписать адрес возврата, например.

char **readLine;

*readLine=NULL;

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

1 голос
/ 10 апреля 2011

В первом случае переменная readLine, значение которой хранится в стеке в отдельной специальной зарезервированной области, является указателем на символ.Когда вы передаете его адрес getline (), вы говорите getline () сохранить реальный указатель в памяти, которая зарезервирована для него.Все работает.

Во втором случае readLine - это указатель на указатель на символ, и снова в нем зарезервировано место в стеке.Когда вы вызываете getline (), вы говорите getline (), что переменная readLine содержит адрес, по которому должен храниться указатель на символ.Но readLine указывает на некоторую случайную память где-то, , а не на местоположение, в котором getline () должно быть разрешено хранить данные.Фактически, вы уже начали портить память, когда пишете

*readLine = NULL;

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

0 голосов
/ 06 марта 2019

Пожалуйста, найдите пример ниже, он скомпилирован и выполнен в Ubuntu 18.04.Если вы используете Linux, пожалуйста, наберите "man getline", man-страницы - ваш друг.

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

int main(int argc, char* argv[])
{
  char *readLine;
  FILE *fp;

  size_t n = 0;
  readLine=NULL;


  fp = fopen("example.c", "r");

   while(getline(&readLine,&n,fp) != EOF){
       printf("%s\n",readLine);
   }
   free(readLine);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...