URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 3919
[ Назад ]

Исходное сообщение
"Глючит прога"

Отправлено rlynx , 06-Фев-05 22:13 
Пытаюсь считать из файла и загнать все что там есть в структуру, не могу понять, в чем проблем:

TData_LoginInfo *strLogin;
strLogin=(TData_LoginInfo*) malloc(sizeof(strLogin));

if((fd = fopen("rreg51.lst", "r"))!=NULL)
{
  fFinish = fopen(fOut, "w" );
  while((fgets(line,100,fd )!=NULL) && (u_index<8100))
  {
     sscanf(line,"%s\t%s\t%s\t%s", s_users[0], s_users[1], s_users[2], s_users[3]);
     strLogin=(TData_LoginInfo*) realloc(strLogin, sizeof(strLogin));
     strLogin[u_index].login=atoi(s_users[0]);
   }

вылетает вот на этом -> strLogin[u_index].login=atoi(s_users[0]);
но не сразу, я по проишествии считывания нескольких строк.
Где я что не так делаю, может есть какой нибудь другой способ? Мне просто надо считать именно в структуру.


Содержание

Сообщения в этом обсуждении
"Глючит прога"
Отправлено XMan , 06-Фев-05 23:18 
Что-то мне подсказывает, что нужно вместо sizeof(strLogin) говорить sizeof(TData_LoginInfo). Очень вероятно, что в первом случае ты выделяешь память для хранения указателя на тип (4 байта), а не самого типа (N байт). При таком раскладе оно может вылетать где угодно - зависит от местоположения выделенной памяти и от фактически выделенного объема (некоторые системы выделяют с выравниванием по параграфам, то есть кратно 16 байт)

"Глючит прога"
Отправлено rlynx , 06-Фев-05 23:38 
>Что-то мне подсказывает, что нужно вместо sizeof(strLogin) говорить sizeof(TData_LoginInfo). Очень вероятно, что
>в первом случае ты выделяешь память для хранения указателя на тип
>(4 байта), а не самого типа (N байт). При таком раскладе
>оно может вылетать где угодно - зависит от местоположения выделенной памяти
>и от фактически выделенного объема (некоторые системы выделяют с выравниванием по
>параграфам, то есть кратно 16 байт)

Не, не помогло...
Что то я делаю не так, а что именно - понять не могу...
Из 180 строк считывает 59 ровно и в любом случае там стопорится. Файл - нормальный, откуда считываю...


"Глючит прога"
Отправлено XMan , 07-Фев-05 03:54 
Ну тогда что есть s_users[] и какова длина буфера line. Особенно последнее.

Кстати, а где изменяется u_index ? :)


"Глючит прога"
Отправлено rlynx , 07-Фев-05 04:00 
>Ну тогда что есть s_users[] и какова длина буфера line. Особенно последнее.
>
>
>Кстати, а где изменяется u_index ? :)

Я творчески порезал :-) Он увеличивается, это я тебя могу заверить, проверял, дебажил :-)
   char s_users[4][128];
   char line[128];

u_index++ у меня стоит в цикле while, не работает просто как раз именно этот кусок.


"Глючит прога"
Отправлено Xenu , 07-Фев-05 06:13 
>>Ну тогда что есть s_users[] и какова длина буфера line. Особенно последнее.
>>
>>
>>Кстати, а где изменяется u_index ? :)
>
>Я творчески порезал :-) Он увеличивается, это я тебя могу заверить, проверял,
>дебажил :-)
>   char s_users[4][128];
>   char line[128];
>
> u_index++ у меня стоит в цикле while, не работает просто как
>раз именно этот кусок.

а что вообще этот код должен делать? нет не в общем, а по шагам.
TData_LoginInfo *strLogin;
объявили указатель на структуру

strLogin=(TData_LoginInfo*) malloc(sizeof(strLogin));
выделили память под структуру, но размером с указатель. На это уже внимание обратили.

if((fd = fopen("rreg51.lst", "r"))!=NULL)
{
открыли файл на чтение и проверили, что открылось
  fFinish = fopen(fOut, "w" );
открыли файл на запись, но не проверили. может быть позже есть проверка
  while((fgets(line,100,fd )!=NULL) && (u_index<8100))
  {
читаем из файла по строкам, пока есть что читать и индекс не превысил 8100
     sscanf(line,"%s\t%s\t%s\t%s", s_users[0], s_users[1], s_users[2], s_users[3]);
распихали прочитанное по массиву строк.
     strLogin=(TData_LoginInfo*) realloc(strLogin, sizeof(strLogin));
перевыделили память под структуру, но опять размером с указатель
     strLogin[u_index].login=atoi(s_users[0]);
записываем хрен знает куда, потому что память выделена на 4 байта, примем что размер указателя 4 байта, а конструкция strLogin[u_index] подразумевает, что по strLogin выделена память под u_index * sizeof(структуры) как минимум.
   }


"Глючит прога"
Отправлено rlynx , 09-Мрт-05 19:31 
Все переделал, но все равно глючит, доходит максимум до 40 с копейками:
#include "stdafx.h"

#include <stdlib.h>
#include <windows.h>
#include <winsock.h>

struct TData{
    int id;
    char word1[128];
    char word2[128];
};

#include "stdafx.h"

int main(int argc, char* argv[])
{
    struct TData *TData_new;
    TData_new=(TData*) malloc(sizeof(TData));
    
    int index=0;
    while(index<10000)
    {
        TData_new[index].id=index;
        strcpy(TData_new[index].word1,"bla");
        strcpy(TData_new[index].word2,"bla");
        printf("%i\t%s\t%s\n", TData_new[index].id,TData_new[index].word1,TData_new[index].word2);
        index++;
        TData_new=(TData*) realloc(TData_new, sizeof(TData));
    }
    index--;

    while(index>=0)
    {
        printf("%i\t%s\t%s\n", TData_new[index].id,TData_new[index].word1,TData_new[index].word2);
        index--;
    }

    return 0;
}


"Глючит прога"
Отправлено XMan , 09-Мрт-05 20:47 
А какой глубокий филосовский смысл в этом коде:

TData_new=(TData*) malloc(sizeof(TData));
...
index++;
TData_new=(TData*) realloc(TData_new, sizeof(TData));

?

Во второй строке совешенно случайно не должно быть чего-то, типа:

TData_new=(TData*) realloc(TData_new, sizeof(TData)*(index+1));

А если убрать "index++", то:

TData_new=(TData*) realloc(TData_new, sizeof(TData)*(++index+1));

?


"Глючит прога"
Отправлено rlynx , 09-Мрт-05 21:11 
>А какой глубокий филосовский смысл в этом коде:
>
>TData_new=(TData*) malloc(sizeof(TData));
>...
>index++;
>TData_new=(TData*) realloc(TData_new, sizeof(TData));
>
>?

Ну, как то изначально же надо было проинициализировать структуру, или не обязательно?
Сразу realloc сделать?

>
>
>
>Во второй строке совешенно случайно не должно быть чего-то, типа:
>
>TData_new=(TData*) realloc(TData_new, sizeof(TData)*(index+1));
>
>А если убрать "index++", то:
>
>TData_new=(TData*) realloc(TData_new, sizeof(TData)*(++index+1));
>
>?

Что то больно хитро, у меня вылечилось так:
TData_new=(TData*) realloc(TData_new, (sizeof(TData)+_msize(TData_new)))
По сути - то же самое...
Правда - я не уверен, что это правильно...


"Глючит прога"
Отправлено XMan , 09-Мрт-05 23:32 
> Ну, как то изначально же надо было проинициализировать структуру, или не
> обязательно? Сразу realloc сделать?

Гм... Нарисуем по другому:

void x=malloc(10);
...
x=realloc(x,10);

Вопрос - изменяется ли размер выделенной памяти после realloc ? :)


> Что то больно хитро, у меня вылечилось так:
> TData_new=(TData*) realloc(TData_new, (sizeof(TData)+_msize(TData_new)))
> По сути - то же самое...
> Правда - я не уверен, что это правильно...

В принципе да. Я просто сократил количество строк на одну за счет "index++" :)


"Глючит прога"
Отправлено rlynx , 10-Мрт-05 00:35 
>> Ну, как то изначально же надо было проинициализировать структуру, или не
> > обязательно? Сразу realloc сделать?
>
>Гм... Нарисуем по другому:
>
>void x=malloc(10);
>...
>x=realloc(x,10);
>
>Вопрос - изменяется ли размер выделенной памяти после realloc ? :)
>
>
>> Что то больно хитро, у меня вылечилось так:
>> TData_new=(TData*) realloc(TData_new, (sizeof(TData)+_msize(TData_new)))
>> По сути - то же самое...
>> Правда - я не уверен, что это правильно...
>
>В принципе да. Я просто сократил количество строк на одну за счет
>"index++" :)


Тогда другой вопрос: если я не буду вообще использовать malloc а только realloc - глюков не будет?


"Глючит прога"
Отправлено rlynx , 10-Мрт-05 01:08 
Блин, под виндами все ок, а под юниксами:
bash-3.00# ./_check
_check in realloc(): warning: junk pointer, too high to make sense

"Глючит прога"
Отправлено Xenu , 10-Мрт-05 03:38 
>Блин, под виндами все ок, а под юниксами:
>bash-3.00# ./_check
>_check in realloc(): warning: junk pointer, too high to make sense

а вы man realloc смотрели ?
realloc() changes the size of the memory block pointed to by ptr to size bytes.  The contents
       will be unchanged to the minimum of the old and new sizes; newly  allocated  memory  will  be
       uninitialized.   If  ptr is NULL, the call is equivalent to malloc(size); if size is equal to
       zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it must have been returned by
       an  earlier  call  to  malloc(),  calloc() or realloc().  If the area pointed to was moved, a
       free(ptr) is done.

то есть память должна быть уже выделена по передаваемому указателю или если еще не выделили то указатель должен быть NULL.


"Глючит прога"
Отправлено XMan , 10-Мрт-05 15:06 
Хм... Подойдем к этому вопросу с другой стороны :)
Для чего ты хочешь использовать realloc ?