c max array size effected by printf - c

I would like to know why some of these programs are throwing a segfault while others aren't.
This program throws a segfault:
#include <stdio.h>
int main(){
int ar[2096263];
printf("asdf");
}
This one doesn't:
#include <stdio.h>
int main(){
int ar[2096263];
}
This program doesn't:
#include <stdio.h>
int main(){
int ar[2096262];
printf("asdf");
}
This one does:
#include <stdio.h>
int main(){
int ar[2096262];
printf("asdf");
printf("asdf");
printf("asdf");
printf("asdf");
printf("asdf");
}
this one doesn't:
#include <stdio.h>
int main(){
int ar[2096262];
printf("asdf");
printf("asdf");
printf("asdf");
printf("asdf");
}
I don't understand why calling printf changes the limit on the size of the array I can have in main. Also, Why can't I have more than 2096262 ints in an array?
Thanks

Due to implementation reasons local variables, including arrays, are stored on the stack. Function calls also add to the stack, both with some meta-information but also with the called functions local variables. It all adds up.
Now, the stack is a limited resource, for example on Windows the default process stack size is only a single MB.
On Linux (which I assume you use since you mention "segmentation fault") the default stack size is 8MB, and with two million four-byte integers on the stack (sizeof(int) is usually 4) you hit that limit and have a stack overflow.

You have declare locally. Local array store in stack section of memory and size of the stack is limited.so, when you give size more than stack, you get segmentation fault. It's also called stack overflow problem.
To have larger arrays, you need to either declare it as a static variable or in file scope.
static int ar[2096263]; // This works fine.

Related

C Array assignment uses brace syntax

I'm working on a display interface with C. Here is the simplified code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define A_BITMAP {1,2,3}
void getA(int **a){
a[0]=(int*)malloc(12);
memcpy(a[0],(int[])A_BITMAP,12);
}
void main(){
int* a;
getA(&a);
printf("%d",a[2]);
free(a);
}
A_BITMAP is one picture's bitmap array, and I cannot modify its code. Here is my question:
Is there any way not using memcpy() to assign to the malloc(ed) area with macro A_BITMAP?
Will (int[])A_BITMAP generate a large local array on stack? The picture's size is about 2M, is it safe to do so?
You can cast it like that. However, casting should be avoided as it's basically telling the compiler you know better than it and disabling any sanity checks it can do. Also, as apparently you don't really know that A_BITMAP is going to be 3 ints, you're opening yourself up to a whole load of pain by hard coding the size.
Moreover, as pointed out by Sunny, it'll likely copy the array onto the stack when written like that (this depends on your compiler, but it's not something I'd like to risk). You really don't want a 2Mb array on the stack, trust me.
A couple of other points:
a isn't an array, it's a pointer so use *a, not a[0], as it's confusing to the reader
you don't return a result from main which means your program
exits with an error.
You might want to consider something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define A_BITMAP {1,2,3}
void getA(int **a) {
static int data[] = A_BITMAP;
*a = malloc(sizeof(data));
memcpy(*a, data, sizeof(data));
}
int main(){
int* a;
getA(&a);
printf("%d\n", a[2]);
free(a);
return 0;
}
It will create the array on the stack each time the function is called.
It will be better if you declare A_BITMAP as a global array as it will not be allocated on stack.

C - Global vs Local multidimensional array

When I execute this code (gcc compiled):
#include <stdio.h>
int main() {
int table[1005][1005];
return 0;
}
it stops working, but when I change it to:
#include <stdio.h>
int table[1005][1005];
int main() {
return 0;
}
it works just fine.. Why is this concretely happening? Does global variables get more space to allocate? Why?
First way is probably creating the array on the stack, the second is probably putting it into the "data segment".
The amount allocated may be too big for the stack depending on your platform.

How to understanding pointers in functions

I have two files, main.c and main2.c. My experience tells me that they should do exactly the same, but they do not.
main.c declares a global variable outside the main routine. Then, inside the main routine, a pointer is declared and defined to point to that global variable. The global variable is changed, and the value of the local variable is printed to screen.
main2.c does the same, but convolutes local-to-global definition and change of global variable value into another function, change_number.
I cannot understand why this approach fails. main.c and main2.c are the boiled down results from a few hours of bugs fixing, documentation and tutorial reading and, obviously, reading here on SO.
My understanding of pointers is what I would call rudimentary: It points to a memory location. In case of a regular variable, the pointer would point to the memory location of that variable. Several pointers can point to the same memory location, but one pointer cannot point to several locations.
There's no such thing as pass-by-reference in C, but, as far as I know, this is not pass by reference since all variable and pointers are defined outside the function. Please enlighten me.
//File: main.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
int main() {
int *local_number;
local_number = &global_number;
global_number = 9;
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "local_number = 9". This is the expected result.
//File: main2.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
void change_number(int *number) {
number = &global_number;
global_number = 9;
}
int main() {
int *local_number;
change_number(local_number);
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "Segmentation fault". This is obviously not intended. The code runs fine right up until printf().
you never initialize local_number in the second program. It does not point anywhere, and will crash when accessed. Try
int *local_number = &global_number;
then the value should change
To have change_number also initialize local_number, pass the address of local_number and change the pointed-to pointer:
void change_number( int **number ) {
*number = &global_number;
global_number = 9;
}
...
int *local_number;
change_number(&local_number);

struct definition inside main() causing Segmentation Fault

Is it not possible to define structure inside main() .
I tried the following only to get a Segmentation Fault:
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1
void main(int argc,char **argv)
{
struct test_struct
{
char test_name[50];
char summary_desc[200];
char result[50];
};
struct suite_struct
{
char suite_name[50];
struct test_struct test[500];
int test_count;
int passed;
int failed;
int unresolved;
int notrun;
}suite[500];
int a,b;
for (a=0;a<500;a++)
{
strcpy(suite[a].suite_name,"");
for (b=0;b<500;b++)
{
strcpy(suite[a].test[b].test_name,"");
strcpy(suite[a].test[b].summary_desc,"");
strcpy(suite[a].test[b].result,"");
}
suite[a].test_count=0;
suite[a].passed=0;
suite[a].failed=0;
suite[a].unresolved=0;
suite[a].notrun=0;
}
}
But the moment I take the struct definition outside it works:
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1
struct test_struct
{
char test_name[50];
char summary_desc[200];
char result[50];
};
struct suite_struct
{
char suite_name[50];
struct test_struct test[500];
int test_count;
int passed;
int failed;
int unresolved;
int notrun;
}suite[500];
void main(int argc,char **argv)
{
int a,b;
for (a=0;a<500;a++)
{
strcpy(suite[a].suite_name,"");
for (b=0;b<500;b++)
{
strcpy(suite[a].test[b].test_name,"");
strcpy(suite[a].test[b].summary_desc,"");
strcpy(suite[a].test[b].result,"");
}
suite[a].test_count=0;
suite[a].passed=0;
suite[a].failed=0;
suite[a].unresolved=0;
suite[a].notrun=0;
}
}
Not sure why this is happening.
I am using the Solaris SunStudio compiler for this.
In the first example, suite lives on the stack, and in the second it lives on the data segment.
Since suite is quite large (~75MB), the segfault is almost certainly due to your program running out of stack space.
In most cases, it is best to allocate large data structures on the heap (using malloc() et al). This will also make it possible to allocate just the amount of space you require instead of always allocating space for 500 elements.
It is okay to declare a structure inside main. But in your program, the problem has got to do with the fact that you are creating 500 objects of that structure inside main function. Each object is about 15 KB in size. So, 500 objects require about 75 MB. Try printf("size: %lu\n", sizeof suite);.
You don't have that much of stack available by default. You can find the available stack using the command ulimit -s. It prints the available stack in KBs.
You can use the ulimit command to increase the stack. e.g. ulimit -s 100000.
A better approach is to dynamically allocate the memory you require using malloc().
It is legal to define a struct and to declare a local variable of that struct inside any function, including main.
But a code can be syntactically legal and crash at runtime (e.g. because it has an undefined behavior, per the C standard, or because it hits some system limitation, like a limit on the call stack).
The struct you define outside of main is global and uninitialized so it will go into the .bss segment and be initialized to 0 at the start of execution. The struct you define inside main is huge and exceeds the maximum stack size (which is about 1-2MB on Linux and probably Solaris too). Since the one outside of main is not on the stack, it appears to work in that case and not the other.
In addition to answers about stack space, malloc, and undefined behavior . . .
When I tried to compile your code, I got 3 warnings.
test.c:7:6: warning: return type of ‘main’ is not ‘int’
test.c: In function ‘main’:
test.c:32:17: warning: implicit declaration of function ‘strcpy’
test.c:32:17: warning: incompatible implicit declaration of built-in function ‘strcpy’
Return an int for main, not void.
int main(int argc,char **argv)
In C, the header for strcpy is string.h, not strings.h.

struct return error-C

this program is written in C
it supposed to get a two D array( matrixAdd) and scan it with scanMtx (the scanning function isn't here becuase the code isn't relevant)
the problem: the EDMtx function return the scanning matrix 1,1,1,,1,-8,1,,1,1,1
when it return back to main it is : 0,0,0,0,0,0,junk,junk,junk
it seems that there is a address error
what did i do wrong?
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
struct matrix
{
int* ptr;
int row;
int column;
};
matrix EDMtx();
void main( int argc, char* argv[])
{
int matrixAdd[5][5]={{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4},{1,1,1,3,4}};
matrix mtx;
matrix scanMtx;
mtx.ptr=&matrixAdd[0][0];
mtx.row=5;
mtx.column=5;
scanMtx= EDMtx();
// mtx= ScanM(mtx,1,1,scanMtx);- doesn't important to you.
getchar();
}
matrix EDMtx()
{
int matrx[3][3]={{1,1,1},{1,-8,1},{1,1,1}};
matrix Mtx;
Mtx.ptr=&matrx[0][0];
Mtx.row=3;
Mtx.column=3;
return Mtx;
}
The variables matrixAdd and matrx, and the memory they point to, have local scope only. If you want them to persist after returning from a function, either declare them static, or redesign your code logic. (e.g. by using malloc to allocate memory explicitly)
In EDMtx, Mtx.ptr is pointed to a stack variable. This is getting destroyed probably. If you want to exchange pointers to variables they must be on the heap
matrix EDMtx()
{
int matrx[3][3]={{1,1,1},{1,-8,1},{1,1,1}};
matrix Mtx;
Mtx.ptr=&matrx[0][0];
Mtx.row=3;
Mtx.column=3;
return Mtx;
}
matrx is a local variable. So, it goes out of scope when upon return of EDMtx(). And the Mtx.ptr has the reference of the local variable matrx. And so the pointer member of scnMtx, is getting garbage values upon dereferencing. Never return references of a local variable.

Resources