nixp.ru v3.0

26 мая 2017,
пятница,
10:20:24 MSK

DevOps с компанией «Флант»
anonymous написал 25 апреля 2006 года в 17:17 (251 просмотр) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

Данный код не работает, как мне надо: срабатывает assert().

Хочу, что бы выделялась память под каждый из указатель в массиве. Где я допустил ошибку? И как ее исправить? Спасибо.

#include 
#include 
#include 
typedef enum
{
      TOKEN_INT,
      TOKEN_CHR,
      TOKEN_DOUBLE,
      TOKEN_NONE
} token_t;
typedef struct
{
      token_t type;
      void* value;
} pair_t;
void initpair(pair_t* arr)
{
      while( arr->type != TOKEN_NONE ){
            switch(arr->type){
                  case TOKEN_INT:
                        arr->value = (int *)malloc(sizeof(int));
                        break;
                  case TOKEN_DOUBLE:
                        arr->value = (double *)malloc(sizeof(double));
                        break;
                  case TOKEN_CHR:
                        arr->value = (char *)malloc(sizeof(char));
                        break;
                  default:
                        break;
            }
            arr++;
      }
}
      
void freepair(pair_t* arr)
{
      while( arr->type != TOKEN_NONE )
            free( arr->value );
}
int* iv = NULL;
double* dv = NULL;
char* cv = NULL;
pair_t arr[] = {
      { TOKEN_DOUBLE, &dv },
      { TOKEN_CHR, &cv },
      { TOKEN_INT, &iv },
      { TOKEN_NONE, NULL }
};
int main(void)
{
      initpair(arr);
      assert( iv != NULL );
      
      freepair(arr);
      return 0;
}
Longobard

Более извращенского способа я не видел.

iliya


...
assert( iv != NULL );
...

Из кода видно, что iv всегда NULL.

Поскольку её никто не меняет, а просто изменяется значение:

...
arr->value=...
...
anonymous


void freepair(pair_t* arr)
{
      while( arr->type != TOKEN_NONE )
            free( arr->value );
}

Вот тут очепятка вкралась. Правда все равно она проблему не решает:

//in loop
{
 free(...);
 arr++;
}


LONGOBARD
Более извращенского способа я не видел.

Это не важно. меня интересует почему не работает как надо :(.

anonymous
iliya
Из кода видно, что iv всегда NULL.

Поскольку её никто не меняет, а просто изменяется значение:

...
arr->value=...
...

Это КАК так??? :o ведь я же память для нее выделяю.

iliya

Ну представь есть у тебя переменная iv — указатель на адрес NULL, она хранится в стеке, и у нее адрес предположим 0xffff, а есть переменная (грубо) arr->value, после передачи в массив &iv ты получаешь, что arr->value = 0xffff. Затем в функции выделяется кусок памяти с адресом 0xdddd и arr->value = 0xdddd, а iv как был так и остался равным нулю, его никто не изменял.

Грубо, но по-моему я ничего не упустил, и особо не наврал.

myst

iliya, садись. Молодец, 5 баллов. :)

rgo
Это не важно. меня интересует почему не работает как надо :(.

а потому, что

typedef struct
{
      token_t type;
      void* value;
} pair_t;

надо писать так:

typedef struct
{
      token_t type;
      union {
          int** ivalue;
          double** dvalue;
          char** cvalue;
      };
} pair_t;

ну или не совсем так, может звёздочек поменьше. И нефиг пользоваться void*, пока в этом нету необходимости. Тогда тебе компилятор такую пачку варнингов выдаст, что пока их разгребёшь, сам поймёшь что же хочешь сделать.

iliya
rgo
а потому, что

typedef struct
{
      token_t type;
      void* value;
} pair_t;

надо писать так:

typedef struct
{
      token_t type;
      union {
          int** ivalue;
          double** dvalue;
          char** cvalue;
      };
} pair_t;

ну или не совсем так, может звёздочек поменьше. И нефиг пользоваться void*, пока в этом нету необходимости. Тогда тебе компилятор такую пачку варнингов выдаст, что пока их разгребёшь, сам поймёшь что же хочешь сделать.

Вот так и пишутся плохие, никому не нужные и не работающие программы: один написал непонятный код, второй исправил, вот и получился GTK.

P.S.

Ничего против gtk , а также разработчиков и людей так или иначе связаных с участием в столь важном и нужном для всего Linux сообщества проекте не имею и сказать не хотел.

Longobard

Блин, извращенцы, откройте для себя С++.

myst

Эээ… батенька, С++ не решает проблемы, он переносит их в другое место. И место это всем хорошо известное…

Longobard
myst
Эээ… батенька, С++ не решает проблемы, он переносит их в другое место. И место это всем хорошо известное…

При использовании идеологии «выделение ресурсов в конструкторе, освобождение в деструкторе» (есть умное название этой идеологии, я его забыл :) ) проблема только одна. И она решается теми же смартпойнтерами.

myst

Технология эта Resource Acquisiton Is Initialization (RAII). :)

rgo
При использовании идеологии «выделение ресурсов в конструкторе, освобождение в деструкторе» (есть умное название этой идеологии, я его забыл :) ) проблема только одна. И она решается теми же смартпойнтерами.

применительно к данному топику, проблема не актуальна нисколько, так что C++ ты сюда зря примазал.

anonymous

Всем спасибо. Вопрос снят. Разобрался ;).