Reputation: 267
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;
}
Upvotes: 0
Views: 156
Reputation: 1149
I think there is something wrong in your func String_New
,when you pass basic_string
to String_New
, it is a pointer actually, that is char *
.So, in 32bit machine, sizeof(char *)
is 4
Upvotes: 0
Reputation: 93534
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 ;
}
Upvotes: 0
Reputation: 2272
I think you're expecting sizeof
to do the same thing that strlen()
does, or what your String_GetSize()
does. That's not what it's intended for.
You're performing sizeof
on the char*
pointer, i.e. "what is the size of this char*
", which is a different question from "how long is the string pointed to by this char*
". On most (if not all) 32-bit platforms sizeof(char*)
will in fact be 4
.
Upvotes: 1
Reputation: 3399
In your helper function String_New(), you are asking for the size of the pointer as opposed to the size of the string when you say "sizeof(basic_string)", thats why you get 4 and not 6. I think what you want is this:-
String String_New(const char* basic_string) {
String temp;
temp.basic_string = (char *) malloc(strlen(basic_string)+1);
strcpy(temp.basic_string, basic_string);
return temp;
}
sizeof measures the sizes of types at compile time; your string arguments will be runtime variables.
Upvotes: 1
Reputation: 1
No, the malloc
inside your String_New
should use the actual run-time length of the string, e.g.
String String_New(char basic_string[]) {
String temp;
int length = strlen(basic_string);
temp.basic_string =
(char *) malloc(length+1); /* 1 more byte for terminating \0 */
strcpy(temp.basic_string, basic_string);
return temp;
}
but you should just use strdup
e.g. temp.basic_string = strdup (basic_string);
Upvotes: 1
Reputation: 96147
char *basic_string;
is a pointer to some memory, the size of the pointer (on a 32bit system) is 32bits = 4bytes. Sizeof doesn't know about the size of memory you have reserved at this address.
There is generally no way to get the size of memory reserved by malloc - although your system may have some private debugging features to do this.
Upvotes: 1