diferent behaviour in different environments for uninitialised malloced memory [duplicate] - c

This question already has answers here:
Why does malloc initialize the values to 0 in gcc?
(10 answers)
Closed 5 years ago.
I was implementing a program related to the use of dynamic allocation in C.
Testing the same piece of code on Visual Studio 2017 and on other IDEs (Dev C ++, Codeblocks, etc.) I have different behaviors:
size_t newDim = 9;
char *p = malloc((newDim + 1) * sizeof(char));
p[newDim] = '\0';
printf("%d\n", strlen(p));
The output of printf() on Visual studio is: 9
other IDEs: 3 sometimes 4.
But when I fill the array with dim-1 characters, the same printf() produces a correct output on the other IDEs. I think that the different compilers have a different way of managing the allocated memory, could someone explain the problem in more detail?
Thank you

malloc is not initializing the memory allocated, so the allocated space might have zeros in arbitrary places giving different string lengths.

Related

How does arrays bypass its declared length [duplicate]

This question already has answers here:
How dangerous is it to access an array out of bounds?
(12 answers)
Why doesn't my program crash when I write past the end of an array?
(9 answers)
Array index out of bound behavior
(10 answers)
No out of bounds error
(7 answers)
Closed 3 years ago.
I was making practises on the logic of arrays in c and my thought on the array length declaration was unformattable if you declare an array length to be 10 integers, that array could not keep 20 integers in memory but when I tested it I saw that I was completely wrong
int main(){
int i;
int arr[10];
for (i = 0;i<20;i++){
arr[i] = i;
}
for (i = 0;i<20;i++){
printf("%d \n",arr[i]);
}
}
I was expecting to see 10 printed numbers but it prints out 20 could someone explain how is it possible?
C and C++ don't have explicit bounds checking on array sizes. When you read/write past the end of an array, you invoke undefined behavior.
With undefined behavior, your program may crash, it may output strange results, or (as in your case) it could appear to work properly. Also, making a seemingly unrelated change such as adding an unused local variable or adding a printf for debugging can change how UB manifests itself.
Just because a program may crash doesn't mean it will.

Why more string is added than allocated memory [duplicate]

This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 6 years ago.
Following is code snippet :
char *b = NULL;
b = new char[5];
if(b != NULL) {
printf("b=%p\n",b);
sprintf(b, "helloPLS...123456789123456789");
printf("b = %s\n", b);
}
output : b = helloPLS...123456789123456789
If only 5 bytes were allocated then why all "helloPLS...123456789123456789" string is added into 5 byte memory?
My program works perfectly fine.
You are writing past the end of memory you allocated. The C standard clearly says the behavior in this case is undefined.
And undefined behavior doesn't mean "always crash". It means it may appear to work. It means the implementation of your C run time environment is within its right to do anything it desires, and that will still be standard compliant.
Undefined behavior is something you should carefully watch out for, precisely because your program may "work perfectly fine" until it just won't.

Crash when trying to make an array overrun [closed]

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
I read this paragraph in c the complete reference book
C has no bounds checking on arrays. You could overwrite either end of
an array and write into some other variable's data or even into the
program's code. As the programmer, it is your job to provide bounds
checking where needed. For example, this code will compile without
error, but it is incorrect because the for loop will cause the array
count to be overrun.
#include <stdio.h>
int main(){
int count[10], i;
/* this causes count to be overrun */
for(i=0; i<15; i++) count[i] = i;
for(i=0; i<15; i++) printf("%d ",count[i]);
return 0;
}
and when I try the code it gives me
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
And then a run time error was displayed on the screen. The error was
array.exe has stopped working
My question is : What is the type of that error? And does it mean that my IDE checks the bounds of the array?
C doesn't check array idexing, it does only simple pointer-arithmetic. That is, the standard defines the operation array[i] as array + i.
Depending on the resulting memory address of that computation, many things can occur:
The address points to the location of a local variable of the function: You modify the local variable. For example:
int main()
{
int array[10];
int a = 0;
array[11] = 22;
printf(a%i,a); /* Prints 22 */
}
Remember that the point here is that buffer overrun has undefined behaviour. My example could not work, because the compiler is free to reorder the variables layout during compilation, for memory-aligment and optimising purposes.
The address points to the location of a global variable (Thats a very big indexing/jump, but can occur): The effect is the same as in the local variable case.
The address points to the location where the subroutine stores the return address: Many architectures stores the return address of a function in a register, but if the architecture stores it in the stackframe of the function... WOW. TRY TO DEBUG THAT!!! :)
The address goes out of the memory space of the process: Modern operative systems always check memory accesses to prevent this, so when this happens the OS kicks you in the ass and throws an exception.
Finally note that things are only applicable in release compilation. In debug mode the compiler adds a lot of code to check this kind of things to throw (Provide) a comprehensible and easy-debuggeable exception.
For example: When allocating dynamic arrays, windows debug-heap first fills the memory space that will be used with a flag which says that memory space is ready to use, but it doesn't contains any data: Thats the hexspeak 0xBADF00D. After this, malloc retrieves the memory location, adding hexspeaks around the array to provide bounds checking.
See this article for a complete explanation.
The moment the first loop reaches i=10, you enter the realm of undefined behaviour (since you're writing past the end of count). From that point on, anything can happen.
Your IDE had nothing to do with it. The OS killed your program because it tried to access memory that didn't belong to it.
This type of error is usually known as an access violation.
That's fine - and the point of the article you have read...
What you are supposed to do is limit the for loop so that it only runs from 0 to 9.
Or, if you really need 15 items, expand the array to take them...

VirtualBox, GCC and Malloc not giving intuitive answer [duplicate]

This question already has answers here:
How dangerous is it to access an array out of bounds?
(12 answers)
Closed 9 years ago.
I am having a odd issue running scientific linux in VirtualBox when compiling this:
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int *arr;
arr = malloc(sizeof(int)*3);
arr[6]=5;
printf("%d", arr[6]);
return 0;
}
my expectation is that I should get garbage when printing out this arr[6] because I have not allocated enough memory for that space.
However, I will compile it with gcc
gcc main.c -o MainTest
then it will output
5
I may be a bit confused but shouldn't the number be some random number
I may be a bit confused but shouldn't the number be some crazy garbage number.
Why? You wrote 5 there. Of course, you wrote into "out of bounds" space, which is an issue. How an implementation should deal with that is not specified by the C standard, which is the point of undefined behavior, but if it just plain does it, what will (generally) happen is either you are still within the process's address space, or else the OS will hand you a segmentation fault (aka. memory access violation) at runtime. Note that this is not determinable at compile time and may vary from run to run and system to system (more points about undefined behavior).
If you are still within the process address space, you still have a significant problem, because you may have overwritten something that was allocated for some other purpose; C will not protect you from that and this can produce very nasty hard to solve bugs.
Have a look at this link :
Sample Code
What i have observed is *arr is storing the starting address of the array and as you are initializing a[6]=5 whats happening is arr+6 the sixth location in the memory from starting is getting filled up with the value you have put and at the time of printing as it is a valid address its printing the value in the address
Update 1:
As long as the value is not modified by other process it outputs the value in that address space.

Why out of bound array accessible in C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Array index out of bound in C
Can a local variable's memory be accessed outside its scope?
C no out of bounds error
I am trying out this code snippet,
#include <stdio.h>
main(){
int a[2],i;
a[5] = 12;
for(i=0;i<10;i++){
printf("%d\n", a[i]);
}
return 0;
}
It gives me output :
1053988144
32767
0
3
0
12
-1267323827
32716
0
0
Why a[5] is accessible ? Shouldn't it through RunTime Error?
C doesn't have bounds-checking on array access, so no it shouldn't. There is nothing in the language stopping you from attempting to read every (virtual) address you can imagine, although often the operating system and/or computer itself will protest, which might generate some kind of exception. Note that just because you "can" (it compiles and run, seemingly without any ill effects), that doesn't mean the program is valid or that it "works". The results of invalid memory accesses are undefined behavior.
int a[2]; means "allocate memory that is 2 * sizeof(int)"
a[5] is syntactic sugar for *(a + 5), which point to an area of memory a + (5 * sizeof(int)). So 3 * sizeof(int) past the end of your array. Where is that? Who knows?
Some languages do bound checking, and I have heard of some C compilers that can do it as well, but most do not. Why not do bound checking? Performance. And performance is a major reason for using C in the first place. But that's OK, because C programmers are good programmers and never go beyond the bounds of an array. (hopefully)
No control is performed on index bounds. This is simply the way C works.

Resources