I'm trying to allocate some memory as unsigned char* however when I do the pointer doesn't seem to have been initialized!
unsigned char* split = (unsigned char*) malloc ((sizeof(unsigned char)*sizeof(unsigned int)));
memset(&split,0,sizeof(int));
if(split==NULL) {
std::cout<<"Unable to allocate memory!\n";
system("pause");
return 1;
}
However every single time I run I get the error message. It seems to happen no matter what data type I use as well!
Your memset call doesn't write to the buffer you've just allocated, the one pointed to by split. It writes to the area of memory where split variable itself stored - as pointed to by &split. Whereupon split becomes NULL.
When you are calling memset(), you are zeroing the memory occupied by the split variable itself, not the memory that split points to (the memory that malloc() allocated). You need to remove the & operator:
unsigned char* split = (unsigned char*) malloc (sizeof(int));
if(split==NULL) {
std::cout<<"Unable to allocate memory!\n";
system("pause");
return 1;
}
memset(split,0,sizeof(int));
Related
I am getting the core dump and I have been looking and it seems I am doing everything right.
int len = 0;
char *buff = NULL;
size_t sz;
if(getline(&buff,&sz, stdin) > 0){
while(isalpha(*buff++))
++len;
printf(" 1st word %d characters long ",len);
}
free(buff);
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
You fail in (1) so you can't do (2). Specifically, what is happening is getline() allocates storage and assigns the beginning address for the allocated block to buff. You then use buff to iterate over the string calling *buff++. When you are done iterating, buff no longer points to (holds the beginning address of) the block of memory allocated by getline().
When you attempt to pass buff to free(), an error occurs because you are attempting to free an address that was not previously allocated by malloc, calloc or realloc.
Use a separate pointer to iterate with, e.g. char *p = buff; within your read loop and iterate with p. (you can also use an index for iterating, e.g. buf[i] without changing the original address buff holds) Then you can pass buff to free().
I am trying to get my head around dynamic memory allocation and was hoping someone could explain why the following code executes as it does.
#include <stdlib.h>
#include <string.h>
char* create_string(void);
int main(){
char* str1 = NULL;
char* str2 = NULL;
str1 = create_string();
str2 = (char*)malloc(11);
str2 = create_string();
printf("String 1 is: %s", str1);
printf("String 2 is: %s", str2);
free(str1);
}
char* create_string()
{
char* stack_str = "TestString";
char* heap_str = (char*)malloc(strlen(stack_str) + 1);
strcpy(heap_str, stack_str);
if(heap_str == NULL)
{
printf("Oh no");
return NULL;
}
return heap_str;
}
As far as I thought, to allocate memory on the heap, you have to use malloc with a size which allocates a block of memory and then use a function such as strcpy() or memcpy(), as I have done with str2 above (malloc 11 for the size of "TestString" plus one for the null terminator.)
I am just confused why assigning the result of create_string to str1 which is a null pointer which has not been allocated a block of memory produces the same output as str2.
Many thanks in advance!
"As far as I thought, to allocate memory on the heap, you have to use malloc with a size which..."
size in malloc() is number of bytes which is unsigned integer. Therefore syntactically str2 = (char*)malloc(11); is correct.
Both str1 and str2 are pointing to different memory locations from the heap containing "TestString". This is according to what you have programmed. However
str2 = (char*)malloc(11); returns 11 bytes of memory that can store character data type and returns a pointer to this location in heap. There is no issue in this.
However, in your code you have leaked this allocation when you assign create_string() pointer to it.
It is not wroking exactly as you think.
Firstly, C has constant strings, which will be initialized by double quotes. Those objects when used, actually return a pointer that points to the location of the initialized constant string array.
char * ptr="something" //"something" return a pointer to the location of the string array
// and is assigned to the ptr.
You don't need to allocate memory for constant string as they are managed by compilers. What's happening in the code is stack_str locates to this constant string array which is managed by the compiler. So it is always present. You create a memory block and stores the address in heap_str, and copies the stack_str contents to the dynamically allocated memory, and returns the pointer.
In effect,
str2 = (char*)malloc(11);
is not used for anything and is wasted. Hope you understands.
Edit: In your create_str(), you check heap_str isn't NULL AFTER strcpy(). If the malloc() failed for some reason, the program will still crash even if you check for NULL.
I don't understand it prints out OneExample when i allocated memory for 5.
I know it is possible to do it using strncpy
But is there a way to do it without using strncpy
It works with strncpy, but is there a way to do it without strncpy ?
void main()
{
char *a;
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
}
It prints out OneExample
Should not it print OneE ??
Can someone explain ?
void main()
{
char *a;
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
}
You aren't using the memory you've allocated. After allocating the memory, you override the pointer a with a pointer to a string literal, causing a memory leak. The subsequent call to free may also crash your application since you're calling free on a pointer that was not allocated with malloc.
If you want to use the space you allocated, you could copy in to it (e..g, by using strncpy).
I don't understand it prints out OneExample when i allocated memory for 5. I know it is possible to do it using strncpy But is there a way to do it without using strncpy
It works with strncpy, but is there a way to do it without strncpy ?
You can use memcpy() as an alternative.
Read about memcpy() and check this also.
Seems that you have some misunderstanding about pointers in C.
Look at this part of your code:
a=(char*)malloc(5);
a="OneExample";
printf("%s",a);
free(a);
You are allocating memory to char pointer a and then immediately pointing it to the string literal OneExample.
This is memory leak in your code because you have lost the reference of the allocated memory.
You should be aware of that the free() deallocates the space previously allocated by malloc(), calloc() or realloc() otherwise the behavior is undefined.
In your program, you are trying to free memory of string literal "OneExample" which will lead to undefined behavior.
Using memcpy(), you can do:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char *a = malloc(5);
if (a == NULL) {
fprintf (stderr, "Failed to allocate memory\n");
exit(EXIT_FAILURE);
}
memcpy (a, "OneExample", 4); // copy 4 characters to a, leaving space for null terminating character
a[4] = '\0'; // make sure to add null terminating character at the end of string
printf("%s\n",a);
free(a);
return 0;
}
Additional:
Using void as return type of main function is not as per standards. The return type of main function should be int.
Follow good programming practice, always check the malloc return.
Do not cast the malloc return.
To use malloc, you need to #include <stdlib.h> which you don't show in your code. The reason is that malloc has a prototype returning a void * and without that prototype, your compiler is going to assume it returns an int. In 64bit architectures, this is a problem, as void * is a 64bit type, and int is 32bit. This makes that the code that extracts the value returned by malloc() to take only the 32 less signifiant bits of the result, and then convert them to a pointer (as per the cast you do, that you shouldn't ---see a lot of comments about this---, and you'll avoid the error you should have got, about trying to convert a int value into a char * without a cast)
After assigning the pointer given by malloc(3) into a, you overwrite that pointer with the address of the string literal "OneExample". This makes two things:
First, you lose the pointer value given by malloc(3) and that was stored in a so you don't have it anymore, and you'll never be able to free(3) it. This is called a memory leak, and you should avoid those, as they are programming errors.
This will be making some kind of undefined behaviour in the call to free(3) that only accepts as parameter a pointer value previously returned by malloc (and this is not the actual address stored in a) Probably you got some SIGSEGV interrupt and your program crashed from this call.
When you do the assignment to a, you are just changing the pointer value that you stored in there, and not the deferred memory contents, so that's what makes sense in calling strcpy(3), because it's the only means to copy a string of characters around. Or you can copy the characters one by one, as in:
char *a = malloc(5); /* this makes a memory buffer of 5 char available through a */
int i;
for(i = 0; i < 4 /* see below */; i++)
a[i] = "OneExample"[i]; /* this is the copy of the char at pos i */
a[i] = '\0'; /* we must terminate the string if we want to print it */
the last step, is what makes it necessary to run the for loop while i < 4 and not while i < 5, as we asked malloc() for five characters, and that must include the string terminator char.
There's one standard library alternative to this, and it is:
char *a = strdup("OneExample");
which is equivalent to:
#define S "OneExample"
char *a = malloc(strlen(S) + 1); /* see the +1 to allow for the null terminator */
strcpy(a, S);
but if you want to solve your example with the truncation of the string at 5, you can do the following:
char *dup_truncated_at(const char *s, int at)
{
char *result = malloc(at + 1); /* the size we need */
memcpy(result, s, at); /* copy the first at chars to the position returned by malloc() */
result[at] = '\0'; /* and put the string terminator */
return result; /* return the pointer, that must be freed with free() */
}
and you'll be able to call it as:
char *a = dup_truncated_at("OneExample", 5);
printf("truncated %s\n", a);
free(a); /* remember, the value returned from dup_truncated_at has been obtained with a call to malloc() */
You need to be clear about what your pointer points to. First, you declare a char *a;. This is a pointer to a character.
In the line a=(char*)malloc(5);, you allocate a bit of memory with malloc and assign the location of that memory to the pointer a. (a bit colloquial, but you understand what I mean). So now a points to 5 bytes of freshly allocated memory.
Next, a="OneExample";. a gets a new value, namely the location of the string OneExample; There is now no longer a pointer available to the five bytes that were allocated. They are now orphans. a points to a string in a static context. Depending on the architecture, compiler and a lot of other things, this may be a static data space, program space or something like that. At least not part of the memory that is used for variables.
So when you do printf("%s",a);, a points to the string, and printf will print-out the string (the complete string).
When you do a free(a);, you are trying to free a part of the program, data etc space. That is, in general, not allowed. You should get an error message for that; in Linux that will be something like this:
*** Error in `./try': free(): invalid pointer: 0x000000000040081c ***
======= Backtrace: =========
/lib64/libc.so.6(+0x776f4)[0x7f915c1ca6f4]
/lib64/libc.so.6(+0x7ff4a)[0x7f915c1d2f4a]
/lib64/libc.so.6(cfree+0x4c)[0x7f915c1d6c1c]
./try[0x400740]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7f915c1737d0]
./try[0x4005c9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 21763273 /home/ljm/src/try
00600000-00601000 r--p 00000000 08:01 21763273 /home/ljm/src/try
00601000-00602000 rw-p 00001000 08:01 21763273 /home/ljm/src/try
[- more lines -]
The statement a="OneExample"; does not mean “Copy the string "OneExample" into a.”
In C, a string literal like "OneExample" is an array of char that the compiler allocates for you. When used in an expression, the array automatically becomes a pointer to its first element.1
So a="OneExample" means “Set the pointer a to point to the first char in "OneExample".”
Now, a is pointing to the string, and printf of course prints it.
Then free(a) is wrong because it attempts to free the memory of "OneExample" instead of the memory provided malloc.
Footnote
1 This automatic conversion does not occur when a string literal is the operand of sizeof, is the operand of unary &, or is used to initialize an array.
the = does not copy the string only assigns the the new value to the pointer overriding the old one. You need to allocate sufficient memory to store the string and then copy it into the allocated space
#define MYTEXT "This string will be copied"
char *a = malloc(strlen(MYTEXT) + 1); //+1 because you need to store the trailing zero
strcpy(a,MYTEXT);
then you can free a when not needed anymore
Firstly here
a=(char*)malloc(5);
you have allocated 5 bytes of memory from heap and immediately
a="OneExample";
override previous dynamic memory with string literal "OneExample" base address due to that a no longer points to any dynamic memory, it causes memory leak(as no objects points that dynamic memory, it lost) here and even after that
free(a);
freeing not-dynamically allocated memory causes undefined behavior.
side note, do read this Why does malloc allocate more memory spaces than I ask for & Malloc vs custom allocator: Malloc has a lot of overhead. Why? to get some more info about malloc().
My goal is to read a file and store it's contents in a char array given the offset and number of bytes to be read. I have written a function for doing the same and it works fine.
Now this function is to be called from somewhere else. So I am trying to declare a variable char * data which will hold the contents returned by the above mentioned function. After declaring I tried to allocate it some memory. (I know how much, as I specify the number of bytes to be read). It goes as follows:
char * data;
char * filename = "alphabet.txt";
int data_size = 10;
printf("data size: %d\n", data_size);
data = (char*) malloc (data_size);
printf("Size allocated to data: %d\n",sizeof(data));
return 0;
This code gives the following output:
data size: 10
Size allocated to data: 8
I don't understand this behavior. Can somebody please explain it to me.
Thanks a lot
shahensha
This has nothing to do with malloc.
sizeof does its thing at compile time, not runtime. sizeof(data) is the same as sizeof(char*). Your program cannot know at compile time how much memory that pointer refers to.
On the other hand, sizeof(some_array) would work as you expect because array sizes are known at compile time.
sizeof char *ptr will give the sizeof the pointer address ptr pointing . Its vary depends on the machine.
char *ptr = malloc(10); malloc will allocate the 10 space and ptr pointing
to the starting address.
Examine below code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * data;
int data_size = 10;
printf("data size: %d\n", data_size);
data = malloc ((data_size+1)*sizeof(char));
strcpy(data, "datadatada");
printf("string lenght: %d\n",strlen(data));
printf("Size allocated to data: %zd\n",sizeof(data));
return 0;
}
Just these two lines of code
char * data;
printf("Size allocated to data: %d\n",sizeof(data));
would print (in OP's machine):
Size allocated to data: 8
sizeof returns the size of the argument, here data pointer. It is done at compile time.
malloc has nothing to do with sizeof(data).
Apparently you made some completely unfounded assumptions about the behavior of sizeof. Apparently you assumed that sizeof can be used to query the size of malloc-ed memory block.
It can't be. sizeof has absolutely nothing to do with that. In fact, C library does not provide you with any means to determine the size of malloc-ed memory block. It is simply impossible. If you want to know how much memory you allocated, you have to devise your own way to remember how much memory you requested from malloc. End of a story.
sizeof evaluates to the size of its operand. In this case you supplied a pointer as its operand, so it evaluated to the size of a pointer, which happens to be 8 on your platform.
I have dynamically allocated 2D array.
Here is the code
int **arrofptr ;
arrofptr = (int **)malloc(sizeof(int *) * 2);
arrofptr[0] = (int *)malloc(sizeof(int)*6144);
arrofptr[1] = (int *)malloc(sizeof(int)*4800);
Now i have to know that how many bytes are allocated in arrofptr,arrofptr[0],arrofptr[1]?
is there any way to know the size?
if we will print
sizeof(arrofptr);
sizeof(arrofptr[0]);
sizeof(arrofptr[1]);
then it will print 4.
You can't find size of arrofptr, because it is only a pointer to pointer. You are defining an array of arrays using that. There's no way to tell the size information with only a pointer, you need to maintain the size information yourself.
The only return value you get from malloc() is a pointer to the first byte of the allocated region (or NULL on failure). There is no portable, standard, way of getting the associated allocation size from such a pointer, so in general the answer is no.
The C way is to represent arrays and buffers in general with a pair of values: a base address and a size. The latter is typically of the type size_t, the same as the argument to malloc(), by the way.
if you want to keep track of the size of an allocated block of code you would need to store that information in the memory block that you allocate e.g.
// allocate 1000 ints plus one int to store size
int* p = malloc(1000*sizeof(int) + sizeof(int));
*p = (int)(1000*sizeof(int));
p += sizeof(int);
...
void foo(int *p)
{
if (p)
{
--p;
printf( "p size is %d bytes", *p );
}
}
alt. put in a struct
struct
{
int size;
int *array;
} s;
You can't get the length of dynamically allocated arrays in C (2D or otherwise). If you need that information save it to a variable (or at least a way to calculate it) when the memory is initially allocated and pass the pointer to the memory and the size of the memory around together.
In your test case above sizeof is returning the size of the pointer, and thus your calculation the size of the pointers is usually 4, this is why you got 4 and is likely to have the trivial result of 4, always.