Why does the heap get corrupted when executing this code? I didn't work with memory allocation that much, yet.
#include <stdlib.h>
void main()
{
char **field, x, _fieldsX, _fieldsY;
_fieldsX = 8;
_fieldsY = 16;
// Allocation
field = malloc(sizeof(char*) * _fieldsX);
for (x = 0; x < _fieldsY; x++)
field[x] = malloc(sizeof(char) * _fieldsY);
// Freeing
for (x = 0; x < _fieldsY; x++)
free(field[x]);
free(field);
}
You get out of the bounds of the allocated area in the first loop:
field = malloc(sizeof(char*) * _fieldsX);
for (x = 0; x < _fieldsY; x++)
field[x] = malloc(sizeof(char) * _fieldsY);
Notice that you are allocating _fieldsX items, but the loop goes _fieldsY times over that area.
The code allocates fields to be _fieldsX in length, but sets _fieldsY elements. This is not correct.
Related
I am getting segmentation fault whenever I do this. I wonder if there is a way for me to assign a value to the struct without getting SegFault?
typedef struct _chunk
{
int lo; // lower bound
int hi; // higher bound
} chunk;
chunk_stack = (chunk **)malloc(10 * 10 * sizeof(chunk **));
for (i = 0; i < chunk_per_thread; i++)
{
chunk_stack[myid][i].lo = 0;
chunk_stack[myid][i].hi = 1;
}
Suppose you need to allocate a 2D array of size r * c.You need to first allocate memory for the double pointer which you did but have an error in it i.e., one extra * inside malloc function.
chunk **chunk_stack = (chunk **)malloc(r * sizeof(chunk *));
Then you need to allocate memory for each of the rows separately.
for(int i = 0; i < r; i++){
chunk_stack[i] = (chunk*)malloc(c * sizeof(chunk));
}
void matrixSetSize(double ***pMatrix, int size) {
if (*pMatrix == NULL) { // void matrix
*pMatrix = (double**)malloc(size * sizeof(double*));
for (int i = 0; i < size; i++)
*(*pMatrix + i) = (double*)malloc(size * sizeof(double));
}
else { // resize existing matrix
double **pointer = (double**)realloc(*pMatrix, 2 * size * sizeof(double*));
for(int i = 0; i < size; i++)
pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));
for (int i = size; i < 2 * size; i++)
pointer[i] = (double*)malloc(size * sizeof(double));
for(int i = 0; i < size; i++)
free(*(*pMatrix + i));
free(*pMatrix);
*pMatrix = pointer;
}
}
Problem: When I try to realocate the size of the matrix, the code won't work and I don't know why. Can someone explain to me why isn't working?
That does not answer your posted code's problem, but could perhaps help you for your bigger picture:
double (*matrix)[size] = malloc(initial_size * initial_size * sizeof(double));
matrix[0][0] = 42;
matrix[size-1][size-1] = 24;
/* resizing */
double (*new_mat)[new_size] = realloc(matrix, new_size*new_size*sizeof(double));
matrix[0][0] = 42;
matrix[new_size-1][new_size-1] = 24;
/* freeing */
free(new_mat);
Isn't it much simpler?
And it's much, much faster to allocate/free, since it's only one allocation.
And it's much, much faster to use, since:
it's one contiguous memory block, so it's cache-friendly
you directly access the cell, you don't have a data dependency on an intermediate pointer.
Please, when you want a 2D-array, make a 2D-array, not a 1D-array-to-pointers-of-N-1D-arrays.
two caveats: 1) if you want to preserve old data on resizing you need to move it manually and 2) your compiler must support C99.
Two problems:
Consider these lines from the reallocation code:
pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));
pointer[i] = (double*)malloc(size * sizeof(double));
In the second you don't allocate as much memory as the reallocation.
After you have reallocated, you free the old data, but it has already been done by the realloc calls.
On an unrelated note, in C you should not cast the result of malloc (or it siblings).
I am making a Rubik's Cube that can rotate it's rows and columns. My struct is this:
typedef struct
{
int **cell;
}face;
In this part I am allocating memory for cells. (X is user input)
face faceOne; //There are six of this faces
faceOne.cell = (int **)malloc(x * sizeof(int));
for(int i = 0; i < x; i++)
faceOne.cell[i] = (int *)malloc(x * sizeof(int));
Then I am filling these cells:
for (int i = 0; i < x; i++)
for (int j = 0; j < x; j++)
{
faceOne.cell[i][j] = 0;
printf("%d\n", i);
}
If x is bigger than 3, program crashes with Segmentation fault. How can i solve this?
faceOne.cell = (int **)malloc(x * sizeof(int));
would be
faceOne.cell = malloc(x * sizeof(int*));
Otherwise you are allocating memory for x int variables and then storing int* variable on it. In case sizeof(int) = sizeof(int*) then it wont be any problem but on the system where this is not the case you have earned yoruself a undefined behavior.
To get rid of all this ** while using malloc the best would be to do this
faceOne.cell = malloc(x * sizeof *faceOne.cell);
Similarly,
faceOne.cell[i] = malloc(x * sizeof *faceOne.cell[i] );
And also don't cast the return value of malloc. This suppresses many warning generated by compiler and is unnecessary.
Apart from all this, have you ever wondered what would happen if malloc did fail and returned NULL? Then you are working on a NULL and dereferencing it(Undefined behavior). Check the return value of malloc, in case it returns NULL handle the error and move on.
You want here
faceOne.cell = (int **)malloc(x * sizeof(int));
to allocate x pointers to int, so this should be
faceOne.cell = malloc(x * sizeof(int *));
It seems on your system the size of a pointer (to int) is bigger than the size of an int ...
Also in C don't cast malloc() (see this)
I'm having a great deal of difficulty with pointers. What I am trying to accomplish sounds, to my ears, rather simple: I want to define a multi-dimensional char array, but not its size, and then have a second method allocate the necessary memory, and fill it up with the requested data.
Now, I've tried for countless hours to accomplish this, searched with Google until my eyes were dry and I still haven't been able to fix it. As such I was hoping any of you had any insight how this would be possible.
What I am imagining, is to define a pointer char** files, and a counter int total_files that will be used my the method print_files(). Print files will then calloc and malloc the variable, and then we'll fill it up with relevant data.
Now in the code below, I have attempted this; however, at runtime I just get the magnificently detailed message: "Segmentation fault (core dumped)". Upon debugging with GDB it points at:
13 *files[i] = malloc(sizeof(char) * 100);
Now, this is for a introductory course to C programming (for Linux), and you might see numerous errors here. I do however, thank you for your time.
I had no issues getting the code to work without the method / pointers, so I'm sure I might just be mixing up the syntax somehow.
#define _SVID_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>
#include <time.h>
int print_files(char*** files, int* total_files) {
int size = 10;
**files = calloc(size, sizeof(char *));
for(int i = 0; i < size; i++) {
*files[i] = malloc(sizeof(char) * 100);
}
*total_files = size;
}
int main() {
char** files;
int num_files;
num_files = 0;
printf("-- Start print_files\n");
print_files(&files, &num_files);
printf("-- end print_files, number of files: %d\n", num_files);
for(int i = 0; i < num_files; i++)
printf("Out: %s\n", files[i]);
printf("total_files=%d\n", num_files);
return 0;
}
**files = calloc(size, sizeof(char *));
This assumes that not only files points to valid memory, but the value at that memory is also a valid pointer pointing to a pointer, which will be changed.
The problem is
char** files;
...
print_files(&files, &num_files);
&files is a valid pointer, but (**(&files)) (as dereferenced by print_files) is an illegal deference because files has not been initialized.
That print_files line should probably read
*files = calloc(size, sizeof(char *));
.
There is also a problem with
*files[i] = malloc(sizeof(char) * 100);
which is equivalent to
*(files[i]) = malloc(sizeof(char) * 100);
I think you probably mean
(*files)[i] = malloc(sizeof(char) * 100);
Here's a working version:
#include <stdio.h>
#include <stdlib.h>
static void print_files(char ***files, int *total_files)
{
int size = 10;
*files = calloc(size, sizeof(char *));
for (int i = 0; i < size; i++)
{
(*files)[i] = malloc(sizeof(char) * 100);
sprintf((*files)[i], "Line %d\n", i);
}
*total_files = size;
}
int main(void)
{
char **files;
int num_files;
num_files = 0;
printf("-- Start print_files\n");
print_files(&files, &num_files);
printf("-- end print_files, number of files: %d\n", num_files);
for(int i = 0; i < num_files; i++)
printf("Out: %s\n", files[i]);
printf("total_files=%d\n", num_files);
return 0;
}
The output is:
-- Start print_files
-- end print_files, number of files: 10
Out: Line 0
Out: Line 1
Out: Line 2
Out: Line 3
Out: Line 4
Out: Line 5
Out: Line 6
Out: Line 7
Out: Line 8
Out: Line 9
total_files=10
valgrind says "leaks like a sieve" but doesn't abuse memory while it is allocated.
What changed?
Triple pointers are scary. However, you want to use only one level of indirection in the assignment with calloc(). (With the double *, GCC warned that files in main() was used uninitialized!) Then, inside the loop, the parentheses around (*files) are critical too. The sprintf() simply serves to initialize the newly allocated string.
I didn't change the main() code significantly.
char **ppchar;
int x;
int y;
ppchar = (char**)malloc(sizeof(char*) * 100);
for (x = 0; x < 100; x++) {
ppchar[x] = (char*)malloc(sizeof(char) * 100);
}
for(x = 0; x < 100; x++) {
for(y = 0; y < 100; y++) {
ppchar[x][y] = rand() % 255; // ascii range
}
}
for(x = 0; x < 100; x++) {
for(y = 0; y < 100; y++) {
// char -128 to 127 or 0 to 255 - it's mostly machine
// dependent. This will tell you.
printf("%d\t",ppchar[x][y]);
}
}
//make sure to clean up the memory
for (x = 0; x < 100; x++) {
free(ppchar[x]);
}
free(ppchar);
return 0;
}
I'm having some trouble with the realloc function.
I'm allocating a dynamic bidimensional array with this function:
Bubble ***allocBubblesMatrix(int height, int width) {
Bubble ***bubblesMatrix = (Bubble***) malloc(height * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (Bubble**) malloc(width * sizeof(Bubble*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = newBubble(rand() % N_BUBBLES);
return bubblesMatrix;
}
wich is called with the next code:
int matrixHeight = 1,
matrixWidth = MATRIX_X_SIZE;
Bubble ***bubblesMatrix = allocBubblesMatrix(matrixHeight, matrixWidth);
This successfuly creates a bidimensional array 1* MATRIX_X_SIZE.
Then, I want to add a row or multiple rows to the matrix, so I use realloc with the following function. It's supposed to add heightIncrement rows. The problem is that sometimes it works, other it crashes de program.
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (Bubble***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (Bubble**) malloc(width * sizeof(Bubble*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
}
This function is called with:
while(true) {
drawBubblesMatrix(x1, y1, matrixHeight, matrixWidth, &bubblesMatrix, bubbles);
resizeBubblesMatrix(&bubblesMatrix, matrixHeight, matrixWidth, 1);
++matrixHeight;
getch();
clear_screen(1);
}
What am I doing wrong?
Function to deallocate the memory blocks previously allocated:
void freeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width) {
int y, x;
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
free((*bubblesMatrix)[y][x]);
(*bubblesMatrix)[y][x] = NULL;
}
free((*bubblesMatrix)[y]);
(*bubblesMatrix)[y] = NULL;
}
free(*bubblesMatrix);
*bubblesMatrix = NULL;
}
Thanks in advance.
EDIT
Silly me. I wasn't doing anything with the return value of realloc as the Karl Knechtel pointed out. But now the program crashes whenever I run it.
With Bart van Ingen Schenau's answer, I confirmed what I feared: I was ignoring the several independent memory blocks that I had allocated previously. I even ended up with a similar code to the one written by Bart but it continues to crash the program.
I've added the assert's to check the results of the malloc/realloc calls and yet I didn't have any luck. I'm using djgpp with Win98 and what's happening it's really odd:
Windows: Sometimes, it never crashes; others, it crashes after adding 2 rows.
MS-DOS: Crashes after adding 2 rows.
I'm gonna try to use -O3 with gcc to get additional clues. What would be a useful (and quick to learn/use) memory corruption/leak detection tool for windows? Is Purify the best solution?
Even my function to free the array is returning page faults.
Read the documentation:
The function may move the memory block to a new location, in which case the new location is returned.... A pointer to the reallocated memory block, which may be either the same as the ptr argument or a new location.
The type of this pointer is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
If the function failed to allocate the requested block of memory, a NULL pointer is returned, and the memory block pointed to by argument ptr is left unchanged.
You cannot correctly use realloc without doing something with the return value. Your code, right now, expects that realloc will always be able to reallocate the memory in such a way that the new block is in the same place. This is clearly impossible; the memory immediately after your array might be in use for something else.
There are a number of things wrong with your use of realloc.
You are passing the wrong pointer to realloc. You should pass the pointer you optained from malloc, which would be *bubblesMatrix.
The 'layout' of the matrices in your allocBubblesMatrix and resizeBubblesMatrix functions is different. In the alloc function, you allocate several independent memory blocks, but in the resize function, you treat it as one big block of memory. That will simply not work.
The correct usage would be:
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
int i;
int newHeight = height + heightIncrement;
for (i = height; i < newHeight; ++i)
(*bubblesMatrix)[i] = (Bubble**) malloc(width * sizeof(Bubble*));
int x, y;
for (y = height; y < newHeight; ++y)
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
But this function still has some issues:
Both malloc and realloc can fail, which is not taken into account here
If heightIncrement is negative, you have a memory leak in the resize function.
I threw together a quick test case, and I have come to the conclusion that the problem you are now experiencing is not in this block of code. I created a very simple test case that replaces the Bubble objects with ints. When I do this, the reallocation completes successfully without crashing. Here is my code:
#include <malloc.h>
#include <assert.h>
int myVal = 0xDEAD;
int ***allocBubblesMatrix(int height, int width);
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement);
int main(int argc, char **argv)
{
int matrixHeight = 1, matrixWidth = 10;
int i = 0;
int ***matrix = allocBubblesMatrix(matrixHeight, matrixWidth);
for(i = 1; i < matrixWidth; i++)
resizeBubblesMatrix(&matrix, matrixHeight, matrixWidth, 1);
printf("Complete!\n");
}
int ***allocBubblesMatrix(int height, int width) {
int ***bubblesMatrix = (int***) malloc(height * sizeof(int**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (int**) malloc(width * sizeof(int*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = &myVal;
return bubblesMatrix;
}
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (int***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(int**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (int**) malloc(width * sizeof(int*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = &myVal;
}
}
The only changes I made were to replace Bubble with int, and to point all the entries in the matrix to a single int variable rather than doing even more allocation.
That means the error is either in drawBubblesMatrix() or in newBubble().
You need to reallocated each dimension separately. You cannot reallocate both dimensions at once, since each "row" was allocated individually.
*bubblesMatrix = (Bubble ***) realloc(bubblesMatrix, (height + heightIncrement) * width * sizeof(Bubble*));
needs to change to
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));