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.
Related
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.
The below code is generated by parsed SIZE parameters which in this case anywhere you see '2512555' is a parsed SIZE parameter. The problem I have is the array is far too large and causes a Segmentation Fault.
Is there a way to overcome the Segmentation Fault without changing the SIZE parameter? This parameter can range from 0 - 400,000.
#include <stdio.h>
#include <stdlib.h>
double templ25_mem1[2512555][2512555];
int main()
{
int templ25_mem1_index1=0;
int templ25_mem1_index2=0;
for(templ25_mem1_index1; templ25_mem1_index1 < 2512555; templ25_mem1_index1++)
{
for(templ25_mem1_index2; templ25_mem1_index2 < 2512555; templ25_mem1_index2++)
{
int rndRow = rand() % 2512555;
int rndCol = rand() % 2512555;
templ25_mem1[rndRow][rndCol] = 0x7FFFFFFF;
templ25_mem1[rndRow][rndCol];
}
}
}
To overcome the Segmentation Fault without changing the SIZE parameter, when size can be that large, you need to redesign your data structure(s).
For erxample, you can have this huge array in a temporary file where you swap parts into your main memory. You may also need two-level addressing because you must make sure you can address the array on disk (45TB is larger than the available address space and probably larger than the largest int).
Best could be to go over the requirements again and see if they really require such a large array, or if they allow for other approaches to achieve their goal(s).
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
I've been struggling with this one for a few hours now and I'm at a loss as to what's happening. This is the code for program.c:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define SPACE 32
#define INITIAL 4
typedef struct {
char *town;
char *country;
} town_t;
typedef struct {
int num_towns, current_size;
town_t **towns_list;
} index_t;
int main(int argc, char *argv[]) {
index_t town_index;
town_index.current_size = INITIAL;
town_index.towns_list = malloc(town_index.current_size * sizeof(*(town_index.towns_list)));
assert(town_index.towns_list != NULL);
printf("Step: %d\n", 1);
town_index.towns_list[0]->town = malloc(4 * sizeof(*(town_index.towns_list[0]->town)));
printf("Step: %d\n", 2);
assert(town_index.towns_list[0]->town != NULL);
return 0;
}
On Linux this is how it runs:
./program
Step: 1
Segmentation fault
but on Windows it prints out
program.exe
Step: 1
Step: 2
as I'd expect, which really isn't helping. For the Linux output, however, clearly the first print statement is being executed but not the second, which would lead me to think that the line between is that one at fault. Particularly, I think doing town_index.towns_list[0] is causing me issues, but I cannot say why.
This is a relatively complex data structure, so maybe I'm getting lost at some point. Basically town_index is meant to be a index struct that contains the current number of towns in towns_list and current_size which reflects the space currently available to save towns. It also contains an array of pointers to town_ts which contain the name and country as strings.
I've tried to use Valgrind, but it's really not helping out much. Here's a Pastebin for those who want to see.
This is a simplified scenario of what I was experiencing in another program, so don't any mind magic numbers and whatnot.
This is on VirtualBox Linux Mint 64-bit.
Unrelated question, if anyone can: How do I get Valgrind to display the precise lines? I see that everywhere else online, but my output just tells me the folder in which the program and function is, which isn't much help.
You initialized town_index.towns_list, but not town_index.towns_list[0], so town_index.towns_list[0]->town is undefined behaviour.
You missed something like
for (int i = 0; i < town_index.current_size; ++i)
town_index.towns_list[i] = malloc(sizeof **town_index.towns_list);
for the second dimension.
town_index.towns_list and town_index.towns_list[0] are not the same. You initialize town_index.towns_list but town_index.towns_list[0] is equal to 0. The crash caused by dereferencing town_index.towns_list[0]
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.