row = n + 1;
col = n + 1;
//used n+1 and i=-1 to avoid segmentation faults
board = malloc(row*sizeof(char *));
for(i=-1;i<row;i++)
{
board[i] = malloc(col*sizeof(char));
if(board[i] == NULL)
{
printf("Out of memory");
exit(EXIT_FAILURE);
}
}
for(i=-1; i < n+1; ++i)
{
free(board [i]);
}
free(board);
When I try to free this array in run time, my compiler goes berserk, please explain, thank you.
arrays cannot have negative index in C.
at the line: for(i = -1; i < row; i++)
I am very sure, there is an off by one error here, where free is freeing one extra block that was not malloc()ed at the end, and you must be getting a segfault error.
malloc returns void pointer, you must cast it. Also minimum index is zero in C.
board = (char**)malloc(row*sizeof(char *));
for(i=0;i<row;i++)
{
board[i] = (char*)malloc(col*sizeof(char));
if(board[i] == NULL)
{
printf("Out of memory");
exit(EXIT_FAILURE);
}
}
Related
This is the code for allocating memory for 2 Arrays of uknown size. N is given by the user:
K=malloc(N*sizeof(int));
if(K==NULL){
// printf("Sorry, cannot allocate memory\n");
return -1;
}
for(i = 0;i < N;i++){
C = malloc(N * sizeof(int *));
if (C == NULL){
return -1;
}
for (i = 0 ; i < N ; i++) {
*(C+i) = malloc(K[i] * sizeof(int));
if (*(C+i) == NULL){
return -1; }
}
}
Both arrays are filled with numbers given by the user.
And to free them:
for (i=0 ; i < N ; i++){
for (i=0 ; i < N ; i++){
free(*(C+i));
}
free(C);
}
void free(void*K);
by debugging with gbd i come across this error
Program received signal SIGSEGV, Segmentation fault.
_int_free (av=0x10102464c457f, p=0x8005770, have_lock=) at malloc.c:4304
4304 malloc.c: No such file or directory.
by using valgrind to go deeper into this error it seems, that i have no leaks.What could be the problem?
for(i = 0;i < N;i++){int *));
if (C == NULL){
return -1;
}
with every iteration the previous allocated memory is lost as the pointer is assigned with the reference to the newly allocated memory block.
if your intention was to change the size of the allocated memory you should use realloc instead
Assuming C is int ** (as per you program logic)
C = NULL;
for(i = 0;i < N;i++){
void *tmp = realloc(C, N * sizeof(*C));
if (tmp == NULL){
free(C);
return -1;
}
C = tmp;
}
int* dynamicArray(int n, int queries_rows, int queries_columns, int** queries, int* result_count) {
int i,j;
int lastAnswer = 0,y,resultCount = 0;
int *result = NULL;
int **seqList = (int**) calloc (n,sizeof(int*));
for (i=0; i<queries_rows;i++)
{
y = (queries[i][1] ^ lastAnswer)% n;
if(queries[i][0] == 1){
if(seqList[y]==NULL){
int *dummy = (int*) calloc (2,sizeof(int));
seqList[y]=dummy;
}
for(j=0;j<n;j++){
if(seqList[y][j])
continue;
else {
printf("%d %d entry %d",y,j,seqList[y][j]);
seqList[y][j] = queries[i][2];
}
}
}
if(queries[i][0] == 2){
lastAnswer = seqList[y][queries[i][2]];
resultCount++;
if(result == NULL)
result = (int*) calloc (1,sizeof(int));
else {
result = (int*) realloc (result,resultCount * sizeof(int));
}
result[resultCount - 1] = lastAnswer;
}
}
*result_count = resultCount;
return result;
}
Anything wrong with the above realloc usage for giving out a "segfault"?
Is this the right way to use realloc?
Also running a debugger is not possible as this is a function completion of cooding site?
You are missing a few spots to "derive" a pointer to do any sort of action with the value...so you're probably trying to allocate/reallocate dynamic memory with the integers memory address instead of the value of the pointer(which would be deriving it).
Try putting an asterisk in front of the pointer variables when allocating/reallocating the memory.
Note these lines
int **seqList = (int**) calloc (n,sizeof(int*));
for (i=0; i<queries_rows;i++)
{
y = (queries[i][1] ^ lastAnswer)% n; // <-- ?
if(queries[i][0] == 1) {
if(seqList[y]==NULL) {
int *dummy = (int*) calloc (2, sizeof(int));
// ^^^
seqList[y]=dummy;
// ^^^
}
for( j = 0; j < n; j++ ) {
// ^^^^^ is n bigger than 2?
if( seqList[y][j] )
// ^^^
continue;
else {
// ...
seqList[y][j] = queries[i][2];
// ^^^
}
}
}
According to what the OP commented "n will be till 10^5", but only enough memory to store a couple of ints has been allocated.
Also note that both calloc and realloc may fail, but none of the values returned by those functions are checked.
Further references to address other issues
Do I cast the result of malloc?
calloc with structure with pointers
Proper usage of realloc
If i have a 2D array allocated as follows:
int** map;
map = malloc(number * sizeof(int*));
if(!(map)){
printf("out of memory!\n");
return 1;
}
for (int i = 0; i < number; i++){
map[i] = malloc(number * sizeof(int));
if (!(map[i])){
printf("Not enough memory!\n");
return 1;
}
}
If the allocation fails and we enter in the if statement should i free map and the "columns" allocated until now? If so, how should i do it?
Right now i just print the message and return 1 but i'm not sure if this is the correct approach.
Yes, you should free() otherwise you leak memory which might matter if this is in a long-running program.
One way to make it easier is to compute the total size of all the allocations, and do a single larger malloc() rather than a whole bunch of smaller ones. This is also (potentially much) faster, since heap allocations can be expensive.
That way, you only need to check once if it succeeded or failed, and there's nothing to free() in case of failure.
Something like this:
int ** map_allocate(size_t number)
{
int **base = malloc(number * sizeof (int *) + number * number * sizeof (int));
if(base != NULL)
{
int *row = (int *) (base + number);
for(size_t i = 0; i < number; ++i)
base[i] = row + i * number;
}
return base;
}
I didn't test-run this, but something along those lines.
You can use:
if (!(map[i])){
printf("Not enough memory!\n");
while (--i>=0)
free(map[i]);
free(map);
return 1;
}
Always set pointers to null immediately you allocate them.
int **map;
map = malloc(number * sizeof(int *));
if(!map)
goto out_of_memory;
for(i=0;i<number;i++)
map[i] = 0;
for(i=0;i<numbers;i++)
{
map[i] = malloc(number * sizeof(int));
if(!map[i])
goto out_of_memory;
}
...
return 0;
out_of_memory:
if(map)
for(i=0;i<number;i++)
free(map[i]);
free(map);
return -1;
I've noticed that I lack of knowledge of dynamic 2D arrays, after reading some topics here and around the web I've tried something but it seem not to behave correctly:
I want to allocate a 3X3 array of integers, input values in to it and display them, the problem is that always after I enter a value at the index of [3][1] the program crashes... it is weird because I think that I've done everything correctly.
I would also like to hear your thoughts about checking for memory allocation failure,(!(array)) good enough method? I've also seen some examples of deallocating memory up to the failure point, if one occurred.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, //loop control
**array, //pointer to hold the 2D array
N = 3; //rows and columns quantity
array = malloc (N * sizeof (int*)); //allocating rows
if (!(array)) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
else
{
array [i] = calloc (N, sizeof (int)); //allocating columns
if (!(array[i])) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
}
for (i = 0; i < N; i++) //getting user input
{
for (j = 0; j < N; j++)
{
printf("Enter value [%d][%d]:", i+1, j+1);
scanf ("%d", &array [i][j]);
}
}
for (i = 0; i < N; i++) //displaying the matrix
{
printf("\n");
for (j = 0; j < N; j++)
{
printf (" %d", array [i][j]);
}
}
exit:
return 0;
}
You have couple of problems.
You are using uninitialized i.
You haven't allocated memory for all the rows. The following line can allocate memory for only one row.
array [i] = calloc (N, sizeof (int)); //allocating columns
What you need:
Instead of
array [i] = calloc (N, sizeof (int)); //allocating columns
if (!(array[i])) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
Use
for ( i = 0; i < N; ++i )
{
array [i] = calloc (N, sizeof (int)); //allocating columns
if (!(array[i])) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
}
You got lucky it didn't crash earlier. You only allocated one row of the 3x3 matrix:
array [i] = calloc (N, sizeof (int)); //allocating columns
if (!(array[i])) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
You need to do this for each row of the matrix, not just once.
Furthermore, when you call calloc, the value of i is undefined. Wrapping the above block in a foor loop should fix your issue:
else
{
for (i = 0; i < N; i++) {
array [i] = calloc (N, sizeof (int)); //allocating columns
if (!(array[i])) //checking for allocation failure
{
printf("memory allocation failed!\n");
goto exit;
}
}
}
I have a quadratic matrix(two-dimensional dynamic array of pointers) and need to change rows/columns order. The matrix is very big that's why I have decided just to change pointers instead of copying all of elements. I also have another array which specifies a computation.
Rows permutation specifies this way:
4,3,2,1 - it means that the first row must be on the fourth place, the second row must be on the third place, etc.
The same situation is with the columns.
How to implement such algorithm of changing of rows order(permutation of of pointers)? Here it is my version, but it doesn't work. I want to copy pointers but element is copied instead of it and then appears a segmentation fault.
When I add '&' to get address, the compiler says that it is a syntax error:
orderOfRows[i] = &auxMatrix[computation[i]];
Here it is my code:
static int N = 6;
static int **orderOfRows;
int **sourceMatrix;
int **auxMatrix;
int main() {
int* computation = (int*)malloc(N*sizeof(int));
computation[0] = 1;
computation[1] = 6;
computation[2] = 3;
computation[3] = 7;
computation[4] = 4;
computation[5] = 2;
}
printf("After computation has been done: \n");
changeRowOrder(computation);
void changeRowOrder(int *computation) {
int i;
// change rows order and dopy them into a temp array
for(i = 0; i < N; ++i) {
// static arrays
orderOfRows[i] = auxMatrix[computation[i]];
}
// recover matrix
for(i = 0; i < N; ++i) {
auxMatrix[i] = orderOfRows[i];
}
void allocate2dMemory() {
int i = 0;
sourceMatrix = (int**)malloc(N * sizeof(int *));
if(sourceMatrix == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
for(i = 0; i < N; i++) {
sourceMatrix[i] = (int*)malloc(N * sizeof(int));
if(sourceMatrix[i] == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
}
auxMatrix = (int**)malloc(N * sizeof(int *));
if(auxMatrix == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
for(i = 0; i < N; i++) {
auxMatrix[i] = (int*)malloc(N * sizeof(int));
if(auxMatrix[i] == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
}
orderOfRows = (int**)malloc(N * sizeof(int *));
if(orderOfRows == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
for(i = 0; i < N; i++) {
orderOfRows[i] = (int*)malloc(N * sizeof(int));
if(orderOfRows[i] == NULL) {
fprintf(stderr, "out of memory\n");
exit(2);
}
}
}
}
I will spend 2*N(copy pointers and then recover) operations instead of N*N.
And I have another question: how I can do the permutation of columns using this idea? If it isn't possible how can I do the permutation of columns but not to copy all elements of the matrix? The programming language is only C.
Instead of
orderOfRows[i] = &auxMatrix[computation[i]];
you should have
for (int j = 0; j < N; ++j)
{
orderOfRows[i][j] = auxMatrix[computation[i]][j];
}
And one more thing:
if you havecomputation[1] = 6, it means that by doing auxMatrix[computation[i]] you try to access auxMatrix[6], which you can't do because auxMatrix's size is 6x6.
If you want to be able to swap both rows and columns without copying, you are going to need to have two auxiliary indices:
int *row_index;
int *col_index;
and access the elements of your matrix using these:
element = matrix[row_index[row]][col_index[col]];
To swap a row or column, you simply swap the corresponding elements of row_index or col_index.