Search code examples
cmemorydynamicallocation

am i doing this right? - C code


when i run this it says the size is 4 when it is really six. it does this here:

printf("String Size: %u\n", sizeof some_string.basic_string);

i am new to c memory allocation and never used malloc before. am i using malloc right?

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

typedef struct String String;

struct String {
  char *basic_string;
};

String String_New(char basic_string[]) {
  String temp;
  temp.basic_string = (char *) malloc(sizeof basic_string);
  strcpy(temp.basic_string, basic_string);
  return temp;
}

void String_Delete(String *string) {
  free(string->basic_string);
  string->basic_string = NULL;
}

int String_GetSize(String string) {
  int i = 0, s = 0;
  while (string.basic_string[i] != '\0') {
    i++;
    s++;
  }
return s;
}

int main(int argc, char *argv[]) {
  String some_string = String_New("hello");
  printf("String Literal: %s\n", some_string.basic_string);
  printf("String Size: %u\n", sizeof some_string.basic_string);
  printf("String Length: %d\n", String_GetSize(some_string));
  String_Delete(&some_string);

  if (some_string.basic_string == NULL) {
    return 0;
  }

  return 1;
}

Solution

  • In C a "string" is not a true data type. The sizeof operator takes a data type, or an object that has "type" as an operand. In your case the object is some_string.basic_string which has type char*, and the size of a pointer on your system is 4.

    The solution is to define your String structure to have a size member:

    struct String {
      char *basic_string;
      size_t length ;
    };
    

    And store the size when allocated in String_New(). This would simplify and make more efficient your String_GetSize() function (which is already over complicated since s == i).

    Be aware also that in String_New(), that the basic_string parameter is also a pointer (despite the "array syntax" used in its signature). I would avoid this syntax, it is misleading since in C you cannot pass an array by copy unless the array is embedded in a struct; arrays always "degrade" to pointers when passed as arguments. Moreover the caller may pass a pointer rather than an array in any case. So in most cases you will have allocated too little memory (4 bytes). You should use strlen() or the method you originally used in String_GetSize() to determine the length.

    String String_New(char* basic_string) 
    {
      String temp;
      temp.length = strlen( basic_string ) ;
      temp.basic_string = (char *) malloc( temp.length + 1 );
    
      strcpy(temp.basic_string, basic_string);
      return temp;
    }
    
    size_t String_GetSize(String string) 
    {
        return string.length ;
    }