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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
#1

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

21.10.2012, 14:04. Просмотров 480. Ответов 5
Метки нет (Все метки)

Здравствуйте, захотелось написать мне более-менее масштабируемую структуру типа словарь, причем без использования шаблонов. Для этого я ввел указатель на функцию сравнения ключей и значений. Но при компиляции/линковки у меня вылетают ошибки
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 минут
Я так понял эти переменные следует переместить в с-файл(файл определения).
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.10.2012, 14:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос При инициализации указателя на функцию происходит ошибка сборки программы (C++):

Ошибка при передаче в функцию указателя на элемент массива - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;ctime&gt; #include &lt;cstdlib&gt; #include &lt;cmath&gt; const int n = 20; int...

Ошибка Access violation при передаче указателя в функцию - C++
выделяю память для нужд програмных и соханяю его. char *resadres =(char*) VirtualAlloc (0, 50000, MEM_COMMIT | MEM_RESERVE,...

Каким образом выделяется память при инициализации строковой константой указателя - C++
Доброго времени суток. Хотелось бы более подробно узнать некоторые моменты относительно указателей и динамического выделения памяти....

Передача указателя структуры в функцию, ошибка на этапе выполнения - C++
Помогите разобратся в чем ошибка. Ошибка вылетает на этапе выполнения. struct book { char * name; char price; static...

Порча указателя при передаче в функцию - C++
Добрый вечер. Проблема такая - при передаче в функцию структуры, полем которой является указатель на указатель, последний портится....

Как сделать функцию от указателя на класс и указателя на метод? - C++
Не получается сделать функцию, параметрами которой являются указатель на класс и на метод. Обращаться к классу нужно именно по указателю,...

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

Ошибки преобразования при передаче указателя на функцию - C++
Есть функция SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, /* An open database */ const...

Ошибка при инициализации - C++
На 3 и 4 строчку показывает отладчик при вылете. BADpixel *enemy; pixel *player; enemy = new BADpixel(75, 10, 10, player); ...

Ошибка нарушения прав доступа при чтении по адресу, возникающая при инициализации трехмерного массива - C++
Очень нужна ваша помощь! Я уже не знаю что тут можно сделать. Код части программы, где вылазит ошибка ниже. Коротко о проблеме: я...

Ошибка при инициализации массива - C++
Что делать? Так как я понимаю, точку с запятой вообще в помине не должно здесь быть!о_О


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.10.2012, 17:15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru