2010-02-10 4 views
1

Строка *array[cnt] = thing вызывает ошибку seg, и я не знаю почему. Любые идеи, чтобы исправить это?C программируемые указатели массивов read file

long *Load_File(char *Filename, int *Size) 
{ 
    FILE *fp; 

    if((fp = fopen(Filename,"r")) == NULL) 
    { 
     printf("Cannot open file.\n"); 
     exit(-1); 
    } 

    fscanf(fp,"%d",Size); 

    int cnt = 0; 
    int items = *Size; 
    long * array[items]; 
    int thing; 

    while (!feof(fp)) 
    { 
     fscanf(fp,"%d",&thing); 
     *array[cnt] = thing; 
     cnt++; 
    } 

    fclose(fp); 

    return *array; 
} 
+2

Вы понимаете, почему это неправильно: 'long * pl; * pl = 42; '? –

+0

OMG, В этом коде слишком много проблем, на которые нужно обратить внимание. В любом случае, я дам вам знать то, что вам нужно изучить (сразу), (1) Область переменных (2) Указатели и массивы, – Alphaneo

ответ

3
long * array[items]; 

объявляет массив указателей на долгий тип данных. Но эти указатели не указывают на что-либо значимое.

Когда вы

*array[cnt] = thing; 

вы разыменования указателя, который является неправильным, так как они не указывают на что-либо значимое.

Вы можете динамически выделить память для массива, как:

long * array = (long*) malloc(size(long) * items); 

, а затем сделать:

while (!feof(fp)) { 
     fscanf(fp,"%d",&arr[cnt++]); 
    } 

, а затем возвращают массив как:

return array; 
+0

Вам нужно убедиться, что в вашем файле есть число «элементов», за которым следует максимальное количество номера. – codaddict

0

Во-первых, этот код не может скомпилировать. Поскольку items не является константой, его нельзя использовать для определения размера массива. Как вы добрались до него, не говоря уже о seg-fault? Помимо этого, и в дополнение к проблеме @codaddict подчеркивает ...

feof не вернется с ошибкой до тех пор, пока fscanf не сработает. Это приведет вас к концу массива. Лучше написать так:

while (cnt < items && fscanf(fp, "%d", &thing)) 
{ 
    /* ... */ 
} 

WRT массив, я думаю, что вы хотели это:

long *array = malloc(sizeof(long)*items); 
/* ... */ 
    array[cnt] = thing; 
/* ... */ 
return array; 
+0

Хотя все остальное, что вы сказали, верное, даже 'return array;' неверно, потому что 'array' является локальным для функции, поэтому вы не можете' return & array [0]; '. –

+0

Вы можете/компилировать его с помощью массивов переменной длины. Однако, как напомнил нам ergosys, вы никогда не должны возвращать указатель на свой стек (включая VLA). Alok, возвращаемый массив не ошибается. Поскольку он malloced, массив указывает на кучу памяти, и это нормально. –

+0

@Matthew, спасибо, что указали это. Я программист до C99. –

0

Изменить

long * array[items]; 

в

long * array = (long *) malloc(sizeof(long) * items); 

Мы динамически выделять память для длинные предметы и храните адрр ess в нашей переменной массива. Ваш синтаксис означает «массив указателей на длину». Новый синтаксис означает «указатель на длинный» (первый из динамического «массива»).

Изменить

*array[cnt] = thing; 

в

array[cnt] = thing; 

Ставим последний читал долго в правильном месте.

Изменить

return *array; 

в

return array; 

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

EDIT:

Благодаря ergosys за напоминание мне, что Власа выделяется в стеке. Удалены предлагаемые изменения в заголовке функции.

+2

Все хорошее, кроме последней части! Возврат указателя в стеке памяти - плохой juju. – ergosys

+0

. Заголовок функции предопределен, и им не разрешено изменять его. – pythonicate

+1

Что сказал эргосис, но похоже, что он должен возвращать значение размера, которое он читает переменной, предоставленной вызывающим пользователем (т. Е. Размер выглядит как [out ]). Имя файла, вероятно, является [in], хотя оно не const, поэтому кто знает. Возвращаемое значение предположительно представляет собой массив longs, поэтому я предполагаю, что ожидалось, что функция выделит массив в куче и вернет указатель. –