C - Global vs Local multidimensional array - c

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.

Related

c max array size effected by printf

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.

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.

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);

Pointer initialization. How does it work?

I finished my programming classes in C, and thought I would write some code down. BOOM! I run into so many problems. I guess the C language is so complicated, even a book can't explain how it works entirely.
This is my problem(I am trying to display something using a pointer)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
char *a;
system("cls");
*a = {"hello"};
printf("%s",a);
getch();
}
*a = {"hello"};
This dereferenced the pointer and assigned something to that memory location. The reason it crashed is because the pointer was uninitialised, ie it did not point at anything (actually it did point at something, but that something was an undefined memory location).
If you had done the following, your program would have worked:
a = "hello";
The type of a is char*. The type of "hello" is also char*.
You don't give value to a pointer to char this way:
*a = {"hello"};
You have to use:
a="hello";
I don't understand very well what you are trying to do. If you only want to print "hello" in your screen, why do you use a pointer to char? What is the getch() for? You use that function this way: http://linux.die.net/man/3/getch Do you intend to read a character?
I would only do:
#include <stdio.h>
main()
{
printf("hello");
}
What are you exactly trying to do?
This is a good reference guide: http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
char *a;// a is pointer which address is store in stack and when u initialize with any string then string is store in code section which cant be change
clrscr();
a = "hello";// this is the way to store the string but if when u assign while declaring as char *a= hello this will accept Remember hello is store in code where as address of pointer a is store in stack section
printf("%s", a);
getch();
}
~
just providing another insight for you..
just now I tried this in Dev-C++ 5.6.3 and it works..
if you assign the value directly when you are declaring it, it works:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
system("cls");
char *a = {"hello"};
printf("%s",a);
getch();
return 0;
}
and one more thing, clrscr is not a standard c function (it didn't work in my test), so how about using cls in stdlib like I did.. hope it's useful..

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