Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача по ссылке / 9 сообщений из 9, страница 1 из 1
22.11.2003, 17:44
    #32332202
viper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
Вот такой вопросик...

Есть функция
char** getdata(int* lines)
lines - кол-во строк в массиве

массив динамический и довольно большой (в общей сложности около 1.5kb)
предположим кол-во строк 150, делаю просто
*lines = arsize // (150)
вывожу на экран все ок, теперь

char** out = NULL;
int lines = 0;

out = getdata(&lines);

массив возвращается правильно но вот вместо line = 150 я получаю чет из серии 875575856... (ну и полный завал соответственно). При меньших размерах возвращаемого массива все ок... Память под массив выделяется до присваивания lines...
Отсюда вопросы
- возможно ли перекрытие? (массив налезает на lines)
- может ли размер возвращаемого значения влиять, на другие переменные? если да то как этого избежать? (варианты сделать массив поменьше или разбить не подходят)
- что вообще делать то?

Вся задача усложняется тем что все пишется на ANSI C под FreeBSD
...
Рейтинг: 0 / 0
22.11.2003, 18:08
    #32332211
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
а исходник?
выдели подозрительное место в отдельную программу и проверь, вполне возможно что проблема не там где ты ее ищеш
...
Рейтинг: 0 / 0
22.11.2003, 18:27
    #32332213
viper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
Так вот не понятно что подозревать при 300 байт работает нормально, при 1.5 Кб нет :(. Должна ведь быть причина? Почему значение теряется (или почему указатель начинает указывать на другую облать)?
_________________________________________________
Легче написать не правильную программу чем понять правильную (С) Alan Perlis
...
Рейтинг: 0 / 0
22.11.2003, 18:39
    #32332216
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
а исходник?
...
Рейтинг: 0 / 0
22.11.2003, 19:05
    #32332224
Передача по ссылке
Точно Точно !
Исходик покаж , а то я честно говоря не телепат .
...
Рейтинг: 0 / 0
24.11.2003, 00:11
    #32332483
viper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
Спасибо за заинтересованость... как только доберусь до работы (в Среду) сразу же покажу исходник...
...
Рейтинг: 0 / 0
26.11.2003, 16:28
    #32335725
viper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
Вот и исходник:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
 /* viper 12/11/2003 last edited: viper 20/11/2003;
*  Получение данных с сервера
* (in) market  - номер маркета
* (in)  com    - команда указывающая необходимые данные
* (out) size  - кол-во строк выходного массива
*/ 
char** getdata(int market, const char* com, int* size)
{
    char buff[BUFFSZ];          //Переменная для хранения ответа от сервера
    char *tmprs = NULL;         //Переменная в которую копируется ответ + \ 0 

    char** res = NULL;          //Переменная для хранения результата (массив 2х2)
    const char* sep =  "\n\r" ;   //Разделитель использующийся для разделения строк в ответе
    char *back, *col;           //Переменные для разбиения строки на массив строк
    long arsize= 0 ;              //Общий размер памяти выделенной под результат
    int stnum =  0 ;              //Кол-во елементов (строк) в результате
    int j= 0 ;                    //Счетчик для цикла

    //Переменные для работы с сокетами
    int s, sz, rz;
    struct sockaddr_in sin;
    struct sockaddr *sp;
    struct in_addr sip;

    sp = (struct sockaddr *)&sin;
    sz = sizeof(sin);

    // Создаём сокет
    s = socket(AF_INET, SOCK_STREAM,  0 );
    if (s == - 1 )
    {
        interr( "Невозможно создать сокет.\n" ,  1 );
        return NULL;
    }

    //Конектимся к определенному серверу
    if (inet_aton(getserver(market), &sip) !=  1 )
    {
        interr( "Неправильно задан адрес сервера.\n" ,  1 );
        return NULL;
    }
    // Задаем адрес сервера и порт
    sin.sin_family = AF_INET;
    sin.sin_port = htons( 1701 );
    sin.sin_addr = sip;

    // Устанавливаем соединение
    if (connect(s, sp, sz) == - 1 )
    {
        interr( "Connection Error\n" ,  1 );
        return NULL;
    }

    // Передаем комманду получения кол. денег в кассах
    if (DEBUG)
        printf( "Передаем комманду: %s\n" , com);
    sendCommand(s, com);

    // Читаем результат
    if (DEBUG)
        printf( "Ожидаем ответа сервера...\n" );

    while( 1 )
    {
        rz = recv(s, buff, BUFFSZ,  0 ); //Получаем ответ

        if (DEBUG)
            printf( "Получено %d байт(ов)\n" , rz);

        buff[rz] = '\0'; //Добавляем симвой конца строки к полученной строке
        tmprs = (char*)malloc(rz+ 1 ); //Выделяем память необходимую для хранения строки + \ 0 
        strncpy(tmprs, buff, rz+ 1 );

        //Печатаем содержимое полученной строки
        if(DEBUG)
            printf( "Buffer: %s\n" , tmprs);

        //Разбиваем полученую строку на массив строк (разделитель '\n\r')
        for(col = strtok_r(tmprs, sep, &back); col; col = strtok_r(NULL, sep, &back))
        {
            if(res == NULL)
            {
                res = (char**)malloc(sizeof(char*));
                arsize += sizeof(char*);
                if(DEBUG)
                    printf( "malloc %d bytes allocated, %d bytes total\n" , sizeof(char*), arsize);
            }
            else
            {
                res = (char**)realloc(res, arsize + (sizeof(char*)));
                arsize += sizeof(char*);
//              if(DEBUG)
//                      printf( "%d bytes allocated, %d bytes total\n" , sizeof(char*), arsize);
            }

            res[stnum] = col;
            stnum++;
        }

        if(!strcmp(res[stnum- 1 ],  "+END" )) //Если нам вернули +END прекращаем считывать...
            break;

    }

    //Выводим на экран полученный массив строк
    if(DEBUG)
    {
        for(j= 0 ; j<stnum; j++)
            printf( "Line %d returned %s\n" , j+ 1 , res[j]);
    }

    *size =  --stnum; //Передать по ссылке кол-во строчек
 

    if(DEBUG)
        printf( "Lines = %d, Actual = %d\n" , *size, stnum);

    if(DEBUG)
        printf( "Total size = %d\n" , arsize); //Выводим на экран общее кол-во выделенной памяти

    // Передаем комманду завершения соединения
    if (DEBUG)
        printf( "Передаем комманду: %s\n" , QUIT);
    sendCommand(s, QUIT);

    if(DEBUG)
        printf( "closing connection\n" );
    // Закрываем соединение
    close(s);

    // Освобождаем выделену память
    free(tmprs);

    if(DEBUG)
        printf( "getdata() done!\n" , *size);

    return res;
}
...
Рейтинг: 0 / 0
26.11.2003, 18:26
    #32335936
Случайный прохожий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
1. Проверь внимательно чтобы размеры массива былы на 1 больше реального (для завершаюшего нуля).

Код: plaintext
1.
2.
char buff[BUFFSZ];          
rz = recv(s, buff, BUFFSZ,  0 ); 
buff[rz] = '\0'; 


не правильно, т.к. если прийдет BUFFSZ байт или больше, то rz станет = BUFFSZ, а buff[rz] = '\0'; - выйдет за границу массива.

Еще видел пару подозрительных мест.

2. Если есть отладчик, пройди всю функцию с просмитром значений size и *size

Удачи.
...
Рейтинг: 0 / 0
27.11.2003, 15:40
    #32336916
viper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача по ссылке
2Случайный прохожий
Спасибо огромное :) даже не представляеш скоко головных болей ты снял...
Эх, стандартная ошибка по не внимательности, а сколько проблем!
Еще раз спасибо...
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача по ссылке / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]