1

I'm quite new to C. I've tried other links but no dice.
I'm using Xcode 6.1 and I get the following issues:

Parse Issue: Expected identifier or '('
Semantic Issue: Unexpected type name 'map'

Here's my code:

//hashmap.h  
#ifndef __HashMap__hashmap__
#define __HashMap__hashmap__

void map_init();
void map_insert(uint8_t, uint8_t);
uint8_t map_getVal(uint8_t);

#endif /* defined(__HashMap__hashmap__) */  

//hashmap.c
#include <stdint.h>
#include "hashmap.h"

#define KEY_NOT_FOUND   -1

static int i = 0;

typedef struct HashMap {
    uint8_t KEY;
    uint8_t VAL;
} *map;

void map_init() {
    map = (HashMap*) calloc(1, sizeof(HashMap));                //Parse Issue
}

void map_insert(uint8_t key, uint8_t val) {
    int size;
    map[i].KEY = key;                                           //Parse Issue
    map[i].VAL = val;                                           //Parse Issue
    i++;
    size = i + 1;
    map = (HashMap*) realloc(map, size * sizeof(HashMap));      //Parse Issue
}

int map_search(HashMap map[], uint8_t key) {
    int index, size = i;
    for(index = 0; index <= size; index++)
        if(map[index].KEY == key)
            return index;
    return KEY_NOT_FOUND;
}

uint8_t map_getVal(uint8_t key) {
    return map[map_search(map, key)].VAL;                       //Semantic Issue
}

I tried replacing map[i] with the pointer array notation (map + i) yields the same result. Also feel free to point out how my hashmap will flop after the issues are fixed.

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Jimmy
  • 189
  • 9
  • Your hashmap will flop because it's not a hashmap. – erip Jun 19 '15 at 20:41
  • your `map` is a type. – Eugene Sh. Jun 19 '15 at 20:42
  • you map variable in `map_insert` `map_getVal` are not declared. in `map_init` map is allocated, but not returned, you haven't stored it. You can either make `map` a static variable or stor the value and pass `map` in for every function call, just like what you did with `map_search` – vincentleest Jun 19 '15 at 20:43
  • You aren't declaring a variable with *map, but a type. Also, if you want to expose struct HashMap to other .c files you are linking with, you will need to move your struct definition to hashmap.h. – Matthew Darnell Jun 19 '15 at 20:47
  • Don't cast the return value of `malloc`, `calloc`, nor `realloc`. Instead, include `stdlib.h`. – zwol Jun 19 '15 at 21:06
  • generally, C coding practice is for #define names to be all CAPS separated by underscore. I.E. #define HASHMAP_H. Note, do not prefix names with underscores. That is 'reserved' for the compiler to do so can cause problems – user3629249 Jun 19 '15 at 21:18
  • regarding this line: (and most/all the other references to 'map') 'map = (HashMap*) calloc(1, sizeof(HashMap));' the struct was given a typedef name of 'map' (always a bad idea to typedef a struct) so each instance of the struct needs to be declared as: 'map myMap' and fields referenced as: 'myMap->fieldName' the 'map' is typedef'd to be a pointer, which is very misleading in the rest of the code. (another good reason to not typedef a struct.) – user3629249 Jun 19 '15 at 21:22

2 Answers2

3

The typedef:

typedef struct HashMap {
uint8_t KEY;
uint8_t VAL;
} *mapEntry;

defines a new type called *mapEntry. You can then create an actual variable:

mapEntry map;

Now, the rest of your code should be parsable as map refers to the variable and not the type.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • `map` is actually a type of pointer to the struct. But the op is using it as variable. – Eugene Sh. Jun 19 '15 at 20:43
  • @EugeneSh. Apologies, my most recent experience with C was a crappy knockoff called "RobotC" (language was not my choice). It didn't really support pointers and I've forgotten a good portion of the syntax. – nanofarad Jun 19 '15 at 20:44
1

Change:

typedef struct HashMap {
    uint8_t KEY;
    uint8_t VAL;
} *map;

with:

typedef struct HashMap {
    uint8_t KEY;
    uint8_t VAL;
} HashMap ;

HashMap *map;
ouah
  • 142,963
  • 15
  • 272
  • 331