N
N
namberden2018-05-04 16:52:44
visual studio
namberden, 2018-05-04 16:52:44

How to solve the problem of incompatibility of const char* with char* type parameter in VS?

In the hash table code, for some reason I get an error in the main, and specifically

int main()
{
    struct listnode *node;
  hashtab_init(hashtab);
  hashtab_add(hashtab, "Tigr", 190); // ошибка на "Tigr"
  hashtab_add(hashtab, "Slon", 2300); // ошибка на "Slon"
  hashtab_add(hashtab, "Volk", 60); // ошибка на "Volk"

  node = hashtab_lookup(hashtab, "Slon"); // ошибка на "Slon"
  printf("Node: %s, %d\n", node->key, node->value);

  return 0;
}

Everything works in the code block.
Error (active) E0167 argument of type "const char *" is incompatible with parameter of type "char *"
code itself.
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "stdafx.h"
#include <math.h>
#include <tchar.h>


#define HASHTAB_SIZE 71 
#define HASHTAB_MUL 31 

struct listnode {
  char *key;
  int value;

  struct listnode *next;
};

struct listnode *hashtab[HASHTAB_SIZE];

int hashtab_hash(char *key) {
  int h = 0;
  char *p;

  for (p = key; *p != '\0'; p++) {
    h = h * HASHTAB_MUL + (int)*p;
  }
  return h % HASHTAB_SIZE;
}

void hashtab_init(struct listnode **hashtab) {
  int i;

  for (i = 0; i < HASHTAB_SIZE; i++) {
    hashtab[i] = NULL;
  }
}

int hashtab_add(struct listnode **hashtab, char *key, int value) {
  struct listnode *node;

  int index = hashtab_hash(key);

  node = (struct listnode *) malloc(sizeof(*node));
  if (node != NULL) {
    node->key = key;
    node->value = value;
    node->next = hashtab[index];
    hashtab[index] = node;
  }
  return NULL;
}

struct listnode *hashtab_lookup(
  struct listnode **hashtab, char *key)
{
  int index;
  struct listnode *node;

  index = hashtab_hash(key);
  for (node = hashtab[index]; node != NULL; node = node->next)

  {
    if (strcmp(node->key, key) == 0) {
      return node;
    }
  }
  return NULL;
}

int main()
{
    struct listnode *node;
  hashtab_init(hashtab);
  hashtab_add(hashtab, "Tigr", 190);
  hashtab_add(hashtab, "Slon", 2300);
  hashtab_add(hashtab, "Volk", 60);

  node = hashtab_lookup(hashtab, "Slon");
  printf("Node: %s, %d\n", node->key, node->value);

  return 0;
}

void hashtab_delete(struct listnode **hashtab, char *key) {
  int index;
  struct listnode *p, *prev = NULL;

  index = hashtab_hash(key);
  for (p = hashtab[index]; p != NULL; p = p->next) {
    if (strcmp(p->key, key) == 0) {
      if (prev == NULL) hashtab[index] = p->next;
      else
        prev->next = p->next;
      free(p);
      return;
    }
    prev = p;
  }
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
devalone, 2018-05-04
@devalone

Change the function signature char * to const char *. If I understand correctly, hashtab_lookup looks for a value by key and there is no need to change it accordingly. And even if the above code compiles and you try to change the string by the pointer, it will be UB.
It would also be nice to format the code in blocks and put the correct question tags (C).

M
Mercury13, 2018-05-04
@Mercury13

There are three ways.
1. Compile with a C compiler, not C++. This works great and gives a warning on return NULL (which is clearly redundant though).
2. Put down const-correctness. Since our structures do not manage strings, but take someone else's, wherever keys are used, make const.

struct listnode {
  const char *key;
  int value;

  struct listnode *next;
};
And so on, there are five places for the entire program.
3. const_cast<char*>(someString). Sometimes it is necessary (for example, to make friends with std::string C++03 and some WinApi functions), but this is not our business.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question