LINUX.ORG.RU

работа с указателями из структуры


0

0

есть код примерно такого вида:
typedef struct
{
token_t type;
void* value;
} pair_t;

...

int* p;
char* q;
double* c;

pair_t arr[] = {
{ TOKEN1, &q },
{ TOKEN2, &p }
{ TOKEN3, &c }
};

Этот массив передается в функции, которые инициализурют поле value: выделяют память, и присваивают значения. Но на выходе переменные p, q, c == NULL. Почему так? И как сделать, что бы память выделялась конкретно для них?

Спасибо.

anonymous

> Этот массив передается в функции, которые инициализурют поле value

функцию покажи

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

например:

void initstr(pair_t* arr)
{
while( arr->type != TOKEN_NONE ){
switch( arr->type ){
case TOKEN1:
arr->value = (int *)malloc(sizeof(int));
arr->value = 10;
break;
....
}

arr++;
}

Соответственно в массив последней строкой нужно добавить что-то вроде { TOKEN_NONE, NULL }. И вызов имеет вид: initstr(cfg), где cfg -- это наш массив.

anonymous
()

> void* value;
...
> int* p;
...
> { TOKEN2, &p }
Ты на самом деле хочешь хранить в value значение типа int**?

gpg
()

Начинаю телепатический сеанс

typedef struct { token_t type; void** value; // 1) } pair_t;

... *arr->value = malloc(sizeof(int)); // 2) **arr->value = 10; // 3)

Ужос. Оно?

gpg
()
Ответ на: комментарий от gpg

долбанное дефолтное форматирование

typedef struct
{
token_t type;
void** value; // 1)
} pair_t;

...
*arr->value = malloc(sizeof(int)); // 2)
**arr->value = 10; // 3)

gpg
()
Ответ на: комментарий от gpg

gpg:

> arr->value = 10; Это описка?
Да, прошу прощения, описка.

> void* value;
...
> int* p;
...
> { TOKEN2, &p }
> Ты на самом деле хочешь хранить в value значение типа int**?
Э-э-э, если на прямую без амперсанда указывать, то gcc выдает предупреждение :/

> Ты на самом деле хочешь хранить в value значение типа int**?
Мне необходимо, что указатели, которые передаются в массив были инициализированы, и что бы к ним можно было бы обращаться как из массива, так и "напрямую".

> Начинаю телепатический сеанс
Спасибо. Вроде бы то, что нужно.

anonymous
()
Ответ на: комментарий от anonymous

>> int* p;
>...
>> { TOKEN2, &p }
>> Ты на самом деле хочешь хранить в value значение типа int**?
>Э-э-э, если на прямую без амперсанда указывать, то gcc выдает предупреждение :/

конешно ругаться будет -- поинтеры то в никуда

anonymous
()
Ответ на: комментарий от anonymous

Выдает такие вот предупреждения:
/tmp$ gcc heap.c -Wall
heap.c:56: warning: initialization from incompatible pointer type
heap.c:57: warning: initialization from incompatible pointer type
heap.c:58: warning: initialization from incompatible pointer type

Часть кода, относящаяся к проблеме выглядит так:
13 typedef struct
14 {
15 token_t type;
16 void** value;
17 } pair_t;

...

51 int* iv;
52 double* dv;
53 char* cv;
54
55 pair_t arr[] = {
56 { TOKEN_DOUBLE, &dv },
57 { TOKEN_CHR, &cv },
58 { TOKEN_INT, &iv }
59 };


Где тут ошибка? Спасибо.

anonymous
()
Ответ на: комментарий от anonymous

>warning: initialization from incompatible pointer type

Это не ошибка. Это предупреждение о возможной ошибке
из-за несоответствия типов.

Попробуй так:

pair_t arr[] = {
   { TOKEN_DOUBLE, (void**)&dv },
   { TOKEN_CHR, (void**)&cv },
   { TOKEN_INT, (void**)&iv }
}; 

kosmonavt
()
Ответ на: комментарий от kosmonavt

kosmonavt:

Не работает. Падает с ошибкой сегментацией при попытке освободить память:
(gdb) run
Starting program: /tmp/a.out

Program received signal SIGSEGV, Segmentation fault.
0x4008e354 in mallopt () from /lib/libc.so.6
(gdb) where
#0  0x4008e354 in mallopt () from /lib/libc.so.6
#1  0x4008d15f in free () from /lib/libc.so.6
#2  0x0804845d in freepair (arr=0x80495e0) at heap.c:47
#3  0x08048489 in main () at heap.c:68

anonymous
()
Ответ на: комментарий от anonymous

Пардон, это я сам виноват. Все выделяется нормально. Но возникает вот такая проблема: бесконечный цикл при освобождении памяти. Вот листинг кода:

        void freepair(pair_t* arr)
     46 {
     47         while( arr->type != TOKEN_NONE )
     48                 free( *(arr->value) );
     49 }
     50
     51
     52 int* iv;
     53 double* dv;
     54 char* cv;
     55
     56 pair_t arr[] = {
     57         { TOKEN_DOUBLE, (void **)&dv },
     58         { TOKEN_CHR, (void **)&cv },
     59         { TOKEN_INT, (void **)&iv },
     60         { TOKEN_NONE, NULL }
     61 };

Т.е. цикл в freepair() крутится бесконечно :(. Где проблема? Спасибо.

anonymous
()
Ответ на: комментарий от anonymous

а увеличивать указатель arr будет кто?

правильно, А.С.Пушкин, наш великий поэт и гражданин :)

anonymous
()
Ответ на: комментарий от anonymous

Вопрос снят, решение найдено :). Всем спасибо за помощь.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.