Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have weird problem: my code is working. Specifically this is working. Why?
char **array = malloc(0);
array[0] = malloc(0);
strcpy(array[0],"hello");
array[1] = malloc(0);
strcpy(array[1],"world");
What the hell is going on? When I replace any of the mallocs with NULL or remove them
it doesn't work but it doesn't seem to matter what value is inside malloc granted it's
not negative.
Dereferencing an invalid pointer is an undefined behavior; so anything can happen.
malloc(0) is implementation-defined and returns either a null pointer or an invalid pointer.
You are invoking undefined behavior by using the pointer returned by malloc(0).
Besides the undefined behaviour of malloc(0). Malloc implementations often have a minimal granularity for the allocated blocks for alignment reasons. Which means that any block will always have at least a size of 4, 8, 12, 16 bytes, depending on implementation. If I remembered correctly, you can even set this value with a mallopt call on certain platforms.
The other thing is, that buffer overflows in allocation code often only crashes when you try to free the pointer(s), because only then is the memory around your block used for internal book keeping used by the library. That's one of the reasons why buffer overflows are so difficult to catch, they manifest at different locations and times then when they occured.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
It is generally advised to assign NULL to a freed up pointer as otherwise it may lead to dangling pointer. I want to know if there is any case where not assigning NULL has some use?
If not, why is it not implemented in the call to 'free()' itself? I understand that the pointer is passed by value and thus cannot be modified. Could the function free() have been be implemented to accept pointer to a pointer(i.e reference to the pointer) where the pointer(not pointer to pointer) points to NULL in the end?
I am asking this since we have to always keep in mind about assigning NULL to pointer after freeing which is a very commonly called function(I am assuming).
Generally it's not for the code but us. cause free doesn't set the pointer to NULL, as if may be needed in some low level situation for some, and more generally the approach of C/C++ is to do things manually by programmer as if they may need specific requirements and this is one the being so pro of C/C++.
Anyway, by setting the pointer to NULL , now if it's happened to be used later in code now we can check if it's NULL or not, and this prevent from dangling and using unallocated memory pointers.
Setting variable to NULL after free
Why is my pointer not null after free?
https://www.quora.com/Why-should-we-assign-NULL-to-the-elements-pointer-after-freeing-them
https://www.acodersjourney.com/top-20-c-pointer-mistakes/
https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152148
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am using the below mentioned to simply learn about malloc. As I have heard and studied that malloc allocate an unintialized storage for you. So the output of this program should be a garbage value. But I am getting 0 as the output. Please tell me what is wrong here?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *x =(int*)malloc(100000000*sizeof(int));
printf("%d",x[0]);
return 0;
}
OUTPUT 0
If malloc returns a null-pointer, and you dereference this null-pointer, you have undefined behavior.
If it doesn't return NULL, then the contents of the memory is indeterminate and using it in any way without initialization is still undefined behavior.
But to explain your behavior, if you get a non-null pointer back, then one of the possible value of the indeterminate values is zero. If you get a null-pointer back, then you might a well might had a crash instead of printing a zero.
Also, some environments might initialize memory to certain values when debugging. Clearing everything (i.e. setting most or everything to zero) is common when running in a debugger
That's the problem with garbage (as well as with undefined behavior) — it could be anything. And among the behaviors that fall under the category of "anything" is looking like it's doing something sensible.
(P.S. you should also test the return value of malloc; errors can happen, and it will signify the error by returning a null pointer)
You are printing the contents of storage with an indeterminate value. This is undefined behaviour. Anything can happen. Some of the things that can happen is the application crashing, your washing machine starting to wash, or your computer printing the number zero.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So the question is, how does the original developer prevent a situation where user/new developer is trying to access a free'd memory element.
int *num=(int *)malloc(n*sizeof(int));
int i;
for(i=0;i<n;i++)
{
scanf("%d",&num[i]);
}
for(i=0;i<n-1;i++){
temp = some_function(x);
}
free(num);
for(i=0;i<n;i++)
{
printf("\nnum[%d]= %d\n",i,num[i]);
}
P.S.: The above code works and actually prints out data in array. Which is not our intention.
[EDIT] Sorry if I was not clear enough. Someone suggested to ask this as a separate question, I thought why not. Here's the original post
The fact that your code "works" is a manifestation of the undefined behaviour that you're experiencing when reading memory that you no longer own.
You could consider setting num to NULL after the first free call. Then writing num[i] will almost certainly crash the program. It can also occasionally be useful: a free called with NULL passed as the pointer is a no-op.
There's little else you can do unfortunately.
But, in general, setting freed pointers to NULL leads to sloppy programming so I tend to avoid it.
The first thing you can do is set num=NULL.
More generally you can add a malloc hook to write garbage to the memory before freeing the memory (probably debug only). This will force a crash if the memory contains pointers or print garbage in this case when accessing freed memory.
Also since you are talking C++, make use of smart pointers.
Edit: fixed up the crash issue.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was writing a simple program and created an array to store 4 integers. Then I used a for loop to assign them; right after that I used the gets() function to get a string; after using the gets() function the first integer on the array would always become a 0. I even printed the variable on the screen before and after the gets() to confirm.
The only thing that fixed it was dynamically allocating the array, so now I want to know if I should always allocate arrays dynamically to prevent this kind of issue?
code:
int nums[4];
int i = 0;
char symbols[3];
for(i=0;i<4;i++){
scanf("%d", &nums[i]);
}
fflush(stdin);
gets(symbols);
calculate(nums, symbols);
No, you should not.
You should allocate arrays dynamically if you don't know their size at compile-time.
If you know the size at compile-time, allocate it statically.
In both cases you should think twice about the size - e.g. if you forget about the '\0' at the end of a C-String you will end up writing in memory you didn't allocate.
In your program, the problem is that you use gets() which is unusably dangerous. It almost certainly overflowed your string, leading to undefined behaviour. In your program, the undefined behaviour manifested itself as an unexpected change to the array of integers. Using dynamic memory allocation changed where the array was stored compared to the string; it changed the undefined behaviour, but didn't fix the problem (which is that you overflowed your string buffer and invoked undefined behaviour when you did so).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
is printf("%d",*(++(*a))); Undefined? Here a is pointer to a pointer to integer.
I do not have anymore code other than this.It is an extension of This question which had created lots of confusions.Just want to know what is happening in this print.Does it depend on Architechture(32 Vs 64) or compiler versions.
Hoping answers will be descriptive and clear.
If you break it down, it does this:
Take the value of what a is pointing at: *a
Increment by one ++(*a)
Dereference that *(++(*a))
So, if the value+1 of what is stored at a is a valid pointer, this will work. Otherwise, the result is undefined and will most likely result in a runtime error.
Yes, your code is correct and even if cryptic can make some (little) sense as in:
void print_next(int **a) {
printf("%d\n",*(++(*a)));
}
int arr[] = {1,5,6,3,5,6};
int *p = arr;
while (p<arr+6)
print_next(&p);
If your question is specifically about *(++(*a)) expression, then there's nothing undefined here (assuming all pointers involved are valid). There are no attempts to perform multiple modifications of the same object. There are no independent reads of any of the modified objects. End of story.
Basically, there's nothing to explain here, since the code is perfectly fine in a rather straightforward manner. There's really no room for anything more "descriptive and clear" than that.
If this is not sufficiently clear, you have to explain what exactly looks suspicious to you in this expression.