Форум программистов, компьютерный форум CyberForum.ru

При инициализации указателя на функцию происходит ошибка сборки программы - C++

Восстановить пароль Регистрация
 
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
21.10.2012, 14:04     При инициализации указателя на функцию происходит ошибка сборки программы #1
Здравствуйте, захотелось написать мне более-менее масштабируемую структуру типа словарь, причем без использования шаблонов. Для этого я ввел указатель на функцию сравнения ключей и значений. Но при компиляции/линковки у меня вылетают ошибки
cmap.o:(.data+0x0): multiple definition of `keyCompareFunc'
preprocessor.o:(.data+0x0): first defined here
cmap.o:(.data+0x4): multiple definition of `valueComapareFunc'
preprocessor.o:(.data+0x4): first defined here
collect2: ld returned 1 exit status

Причем ссылаются эти ошибки на несуществующие файлы. В чем может быть проблема? (указанные указатели находятся в cmap.h в строчках 8 и 9 )Вот код:
cmap.h
C
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
#ifndef CMAP_H
#define CMAP_H
 
#include <string.h>
 
typedef const char * TKey;   // тип ключа
typedef const char * TValue; // тип значения
 
int (*keyCompareFunc)(TKey, TKey) = strcmp;         // функция сравнения ключей
int (*valueComapareFunc) (TValue, TValue) = strcmp; // функция сравнения значений
 
struct Map
{
   TKey key;
   TValue value;
   struct Map *left;  // левое поддерево (для меньших значений)
   struct Map *right; // правое поддерево (для больших значений)
};
 
// имеет ли словарь такой ключ, в случае отсутствия такого возвращает NULL,
// иначе структуру Map, содержащий искомый ключ
struct Map * cmap_has_key(struct Map *rootMap, TKey key);
TValue cmap_get_value(TKey key); // возвращает значение по ключу
int cmap_insert(struct Map **rootMap, TKey key, TValue value);
int cmap_clear(struct Map **mapRoot); // очищает словарь
int cmap_empty(struct Map *mapRoot); // проверяет на пустоту словарь
int cmap_delete(struct Map **mapRoot, TKey key); // удаляет по ключу
 
enum CMAP_ERROR{
   CMAP_NUL_POINTER = 1,
   CMAP_KEY_NOT_FOUND
};
 
#endif // CMAP_H

cmap.c
C
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
#include "cmap.h"
 
#include <stdlib.h>
 
 
 
// ------------------------------------------------------------
int cmap_insert(struct Map **rootMap, TKey key, TValue value)
{
   if (!rootMap)
      return CMAP_NUL_POINTER;
 
   struct Map *newNode = malloc(sizeof (*newNode));
 
   newNode->key = key;
   newNode->value = value;
   newNode->left = NULL;
   newNode->right = NULL;
 
   if (*rootMap == 0)
   {
      // пустое дерево, новый элемент есть новый корень
      *rootMap = newNode;
   }
   else
   {
      struct Map *curNode = *rootMap; // текущий узел
      int iCmp; // хранит значение функции сравнения ключа текущего узла и ключа вставки
 
      while (1)
      {
         iCmp = keyCompareFunc(curNode->key, key);
 
         if (iCmp < 0)
         {
            // ключ вставки меньше ключа текущего узла
            if (curNode->left != NULL)
               curNode = curNode->left;
            else
            {
               curNode->left = newNode;
               break;
            }
         }
         else if (iCmp > 0)
         {
            // ключ вставки больше ключа текущего узла
            if (curNode->right != NULL)
               curNode = curNode->right;
            else
            {
               curNode->right = newNode;
               break;
            }
         }
         else
         {
            // ключ вставки равен ключу текущего узла. В таком случае просто обновляем значение узла
            curNode->value = value;
            break;
         }
      }
   }
 
   return 0;
}
// ------------------------------------------------------------
struct Map * cmap_has_key(struct Map *rootMap, TKey key)
{
   if (!rootMap)
      return 0;
 
   struct Map *curMap = rootMap;
   int iCmp;
 
 
   while (1)
   {
      iCmp = keyCompareFunc(curMap->key, key);
 
      if (iCmp < 0)
      {
         if (curMap->left == NULL)
            return NULL;
         else
            curMap = curMap->left;
      }
      else if (iCmp > 0)
      {
         if (curMap->right == NULL)
            return NULL;
         else
            curMap = curMap->right;
      }
      else
      {
         return curMap;
      }
   }
}
// ------------------------------------------------------------

PS: в файле preprocessor.c тоже происходит include cmap.h

Добавлено через 7 минут
Я так понял эти переменные следует переместить в с-файл(файл определения).
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
21.10.2012, 14:11     При инициализации указателя на функцию происходит ошибка сборки программы #2
в h файле оставляй их как extern int (*keyCompareFunc )( TKey, TKey ),
а строки с определением (как у тебя сейчас) унеси в C файл.
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
21.10.2012, 14:15  [ТС]     При инициализации указателя на функцию происходит ошибка сборки программы #3
Герц, а по мне так лучше оставить их в c-файле как static, им большая видимость не нужна
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
21.10.2012, 14:18     При инициализации указателя на функцию происходит ошибка сборки программы #4
Я не в курсе, где они у тебя используются.
А так да, если они принадлежат только C файлу - я бы объявил static.
I.M.
 Аватар для I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
21.10.2012, 15:16     При инициализации указателя на функцию происходит ошибка сборки программы #5
Buckstabue, может удобнее будет использовать std::function ?
Buckstabue
 Аватар для Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
21.10.2012, 17:15  [ТС]     При инициализации указателя на функцию происходит ошибка сборки программы #6
I.M., к сожалению, разрешено использовать только возможности компилятора gcc(не g++) версии 4.1.3
Yandex
Объявления
21.10.2012, 17:15     При инициализации указателя на функцию происходит ошибка сборки программы
Ответ Создать тему
Опции темы

Текущее время: 21:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru