Allocation large memory in visual studio C - c

I am using visual studio C in window to write a function to allocate large memory. If I test it with small value(small than 3000x6000-3000 is number of rows and 6000 is number of columns), it will be correct. However, when I test with large value about (30000,60000), It will error with message "Unhandled exception at 0x0f6bc9d0 in LargeMemory.exe: 0xC0000005: Access violation writing location 0x00000000." -0x0f6bc9d0 is address of 2D point. How to resolve this problem. This is my code
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <memory.h>
int** memoryAllocation()
{
int nRow=30000;
int nColumn=60000;
int **ppnGMatrix=NULL;
ppnGMatrix =(int**)malloc(sizeof(int*)*nRow);
if(ppnGMatrix!=NULL)
{
for (int nRowIndex = 0; nRowIndex < nRow; nRowIndex++)
{
ppnGMatrix[nRowIndex] = (int*)malloc(sizeof(int) * nColumn);
memset(ppnGMatrix[nRowIndex], 0, sizeof(int) * nColumn);
}
}
return ppnGMatrix;
}
int _tmain(int argc, _TCHAR* argv[])
{
int** GMatrixAllocate=NULL;
GMatrixAllocate=memoryAllocation();
return 0;
}

You are trying to allocate 1.8*4GB of memory.
First: Make sure you are compiling as a 64 bit executable, 1.8*4GB will use more memory space than is available in 32bit. Even if you have that much space free in your address space it may not be contiguous (all in one block) which is what malloc will look for.
Second: redesign your code, any time you get to a point where you need contiguous blocks of such a huge size it probably means you need to reconsider your approach.

Related

calloc function generating zeros instead of memory addresses

I'm trying to create a graph with 264346 positions. Would you know why calloc when it reaches 26,000 positions it stops generating memory addresses (ex: 89413216) and starts generating zeros (0) and then all the processes on my computer crash?
The calloc function should generate zeros but not at this position on my code.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#include <limits.h>
int maxV;
struct grafo {
int NumTotalVertices;
int NumVertices;
int NumArestas;
int **p;
};
typedef struct grafo MGrafo;
MGrafo* Aloca_grafo(int NVertices);
int main(){
MGrafo *MatrizGrafo;
MatrizGrafo = Aloca_grafo(264346);
return 0;
}
MGrafo* Aloca_grafo(int NVertices) {
int i, k;
MGrafo *Grafo ;
Grafo = (MGrafo*) malloc(sizeof(MGrafo));
Grafo->p = (int **) malloc(NVertices*sizeof(int*));
for(i=0; i<NVertices+1; i++){
Grafo->p[i] = (int*) calloc(NVertices,sizeof(int));// error at this point
//printf("%d - (%d)\n", i, Grafo->p[i]); // see impression
}
printf("%d - (%d)\n", i, Grafo->p[i]);
Grafo->NumTotalVertices = NVertices;
Grafo->NumArestas = 0;
Grafo->NumVertices = 0;
return Grafo;
}
You surely dont mean what you have in your code
Grafo = (MGrafo*)malloc(sizeof(MGrafo));
Grafo->p = (int**)malloc(NVertices * sizeof(int*)); <<<<=== 264000 int pointers
for (i = 0; i < NVertices + 1; i++) { <<<<< for each of those 264000 int pointers
Grafo->p[i] = (int*)calloc(NVertices, sizeof(int)); <<<<<=== allocate 264000 ints
I ran this on my machine
its fans turned on, meaning it was trying very very hard
after the inner loop got to only 32000 it had already allocated 33 gb of memory
I think you only need to allocate one set of integers, since I cant tell what you are trying to do it hard to know which to remove, but this is creating a 2d array 264000 by 264000 which is huge (~70billion = ~280gb of memory), surely you dont mean that
OK taking a comment from below, maybe you do mean it
If this is what you really want then you are going to need a very chunky computer and a lot of time.
Plus you are definitely going to have to test the return from those calloc and malloc calls to make sure that every alloc works.
A lot of the time you will see answers on SO saying 'check the return from malloc' but in fact most modern OS with modern hardware will rarely fail memory allocations. But here you are pushing the edge, test every one.
'Generating zeros' is how calloc tells you it failed.
https://linux.die.net/man/3/calloc
Return Value
The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable. On error, these functions return NULL. NULL may also be returned by a successful call to malloc() with a size of zero, or by a successful call to calloc() with nmemb or size equal to zero.

programming in C: "expected constant expression" error in Visual Studio

I am following this video tutorial on sorting arrays using C code. Unlike the video, which uses codeBlocks, I am using Visual Studio to compile/run my code. When attempting to run the following
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
int i,temp,swapped;
int howMany = 10;
int goals[howMany];
return 0;
}
I get the following error:
Error 1 error C2057: expected constant expression d:\temp\c tutorials\c tutorials\main.c 17 1 C Tutorials
Error 2 error C2466: cannot allocate an array of constant size 0 d:\temp\c tutorials\c tutorials\main.c 17 1 C Tutorials
I am using exactly the same code as on the video. Why will visual studio not allocate 10 bits of memory using the previously declared howMany variable?
You could allocate dynamically, use malloc or calloc. Note that by this way, you are allocating from the heap.
#include <stdlib.h>
const int howMany = 10;
int* goals = malloc(howMany * sizeof(int));
You should check the pointer in case malloc failed:
if (goals == NULL){
/* Something went wrong, act accordingly */
} else{
/* Move on in here, or just don't write the else part at all */
}
Then you can access this array by indexing:
goals[0] = 2017;
If you need to resize this array, you can use realloc. However while doing this, first use a new pointer and then check it again. Suppose you needed a bigger array in run-time. In this case, I will assume howMany wasn't declared as const int so it can be reassigned without some pointer hack.
howMany = 50;
int* temp_new_goals = realloc(goals, howMany * sizeof(int));
if (temp_new_goals == NULL){
/* Something went wrong again */
} else{
/* No problems, assign the new pointer. Don't worry, your old data remains still. */
goals = temp_new_goals;
}
At the end, don't forget to free the memory you allocated. You don't want memory leaks:
free(goals);
You can simply define like this,
int goals[10];
Or you can modify howMany to const like this,
const int howMany = 10;
Or you can define howMany as a macro outside like this,
#define howMany 10

Freeing an array of mpc_t in C

I'm new to C programming and I couldn't find solution to my problem. Although the code works (I've been able to include it in other program), when it tries to free the memory assigned by calloc(), it returns the following error:
free(): invalid next size (normal):
followd by what appears to be a memory address. I'm using mpc libraries (for arbitrary precision complex numbers). This is the smallest program that repeats the error:
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>
int N = 10;
int precision = 512;
int main(void) {
mpc_t *dets2;
dets2 = (mpc_t*)calloc(N-2,sizeof(mpc_t));
for (int i = 0; i<=N-2; i++) {
mpc_init2(dets2[i],512); //initialize all complex numbers
mpc_set_str(dets2[i],"1",0,MPFR_RNDN); //set all the numbers to one
}
free(dets2); //release the memory occupied by those numbers
return 0;
}
Thanks for your help!
Your for loop breaks after i == N-2, but it should break before. The condition in your for loop should be i<N-2 instead of i<=N-2.
So you try to access memory, which is out of bounds. This leads to undefined behaviour, so anything can happen, including a segmentation fault, a free run time error or nothing.

C - creating an array at runtime with size greater than 10M

I want to create an array at runtime in C of approximately 10M rows, whose precise size is only known at runtime. Here is a first cut at it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
printf("running\n");
long long size = atoi(argv[1]);
printf("%lld\n", size);
int myArray[size];
printf("allocated array\n");
for (long long i = 0; i< size; i++) {
myArray[i] = 1;
}
printf("Done");
}
My issue is that this segfaults.
>./a.out 100000000
running
100000000
Segmentation fault: 11
I think I have to do a malloc to get this working, but I can't quite get it right.
There's no portable way to detect the failure of automatic allocation. On linux, you could check it by using ulimit -s and set it to unlimited: ulimit -s unlimited.
But even this doesn't tell you whether such a large allocation was successful. Safer way is to use dynamic allocation using malloc() and check if allocation was successful:
int *myArray = malloc( size * sizeof *myarray);
if(!myarray) { /* allocation failed */}
there are two suggestions:
write a function which receives a argument which is INT(or which type you want) type,then you can put a value to it when running,and then ,you can do your thing.
try malloc.

How to assign some part of dynamic array to whole static array

The size of dynamic array is the twice the size of static array. I want to assign the values which starts from (N/2)-1 to N-1 of dynamic array to whole static array.
The only way is copying the values with a loop?
My code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
int N=100, pSize=4, lSize, i;
double *A;
lSize=N/sqrt(pSize);
/* memory allocation */
A=(double*)malloc(sizeof(double)*N);
double B[lSize];
/* memory allocation has been done */
/* initilize arrays */
for(i=0; i<lSize; i++){
B[i]=rand()% 10;
}
A=B;
for (i=0; i<lSize; i++){
fprintf(stdout,"%f\n", A[i]);
}
return 0;
}
You can use the memcpy function to copy the data. For your example you want to copy the last half of A to B so could do something like:
memcpy(&B[0], &A[lSize-1], lSize * sizeof(double));
Note: On the MinGW compiler I was using, it was requiring that I declare the destination as &B[0], I thought I could get away with just B. It may be due to configuration I have (I don't use the C compiler all that much, normally just use g++ for quick C++ test cases).
You can use memcpy to copy contiguous chunks of memory around.
Your program leaks your allocation, which is probably bad - is that A=B intended to be where you would put the code that copies the array?
It may be possible, depending on your architecture, to do a copy without a CPU loop (via a call to a DMA engine or something). In standard C, you have no choice but to loop. You can either do it yourself or you can call memcpy(3), memmove(3), or bcopy(3) if you prefer to use the library's implementations.
As said, you need to use memcpy:
#define N 100
int staticarray[N];
int *pointer = (int*) malloc( sizeof(int)*N*2 );
memcpy( staticarray, (pointer + ((N/2) - 1)), sizeof(int)*N );

Resources