I am converting integers to strings and adding them to a dynamically allocated array. The problem is that it is causing a segfault. I don't understand why it is happening.
#include <stdio.h>
#include <stdlib.h>
int main() {
char *x = malloc(10 * sizeof(char));
x[0] = malloc(10 * sizeof(char));
sprintf(x[0],"%d",10);
for(int i = 0; i < 10;i++){
free(x[i]);
}
free(x);
return 0;
}
To allocate an array whose elements are char*, the pointer to point the array should be char**, not char*.
Also you mustn't use values in buffer allocated via malloc() and not initiaized. The values are indeterminate and using them invokes undefined behavior.
#include <stdio.h>
#include <stdlib.h>
int main() {
/* correct type here (both variable and allocation size) */
char **x = malloc(10 * sizeof(char*));
x[0] = malloc(10 * sizeof(char));
sprintf(x[0],"%d",10);
/* initialize the other elements to pass to free() */
for (int i = 1; i < 10; i++) x[i] = NULL;
for(int i = 0; i < 10;i++){
free(x[i]);
}
free(x);
return 0;
}
If you want a dynamic allocated array of strings, you should declare your variable x as a pointer to an array of e.g. 32 chars. The you can allocate/deallocate an array of these using a single malloc and likewise a single free.
Like:
#define NUM_STRINGS 10
#define STRING_SIZE 32
int main() {
// declare x as a pointer to an array of STRING_SIZE chars
char (*x)[STRING_SIZE];
// Allocate space for NUM_STRINGS of the above array, i.e.
// allocate an array with NUM_STRINGS arrays of STRING_SIZE chars
x = malloc(NUM_STRINGS * sizeof *x);
if (x)
{
for (int i = 0; i < NUM_STRINGS; ++i)
{
sprintf(x[i], "%d", 10 + i);
}
for (int i = 0; i < NUM_STRINGS; ++i)
{
puts(x[i]);
}
free(x);
}
return 0;
}
Output:
10
11
12
13
14
15
16
17
18
19
The best way to determine the amount of memory to be used with malloc is this:
#include <stdio.h>
#include <stdlib.h>
#define N_STRINGS 10
#define STRING_SZ 10
int main() {
// if you use *x (the deferred subexpression) the compiler can calculate its
// sizeof easily, and no need to use a constant or something that has to be
// revised if you change the type of x. Also, calloc will give instead N_STRINGS
// pointers already initialized to NULL.
char **x = calloc(N_STRINGS, sizeof *x);
// to be able to free(x[i]) for all i, you need to initialize all pointers,
// and not only the first one.
int i; // I prefer this, instead of for(int i..., which is more portable with legacy code.
for (i = 0; i < N_STRINGS; i++) {
// char is warranted to be sizeof 1, you don't need to specify but the
// number of chars you want for each character array.
x[i] = malloc(STRING_SZ); // remember only STRING_SZ chars you have, so...
// better to use snprintf(), instead.
snprintf(x[i], // the buffer pointer
STRING_SZ, // the buffer size (STRING_SZ chars, incl. the final null char)
"%d", // the format string
10); // initialize all strings to the string "10" ???
}
// upto here we have made N_STRINGS + 1 calls to malloc...
// you should do something here to check that the allocations went fine, like
// printing the values or do some work on the strings, but that's up to you.
// now, everything should be fine for free() to work.
for(int i = 0; i < N_STRINGS; i++){
free(x[i]);
}
free(x); // ... and this is the N_STRINGS + 1 call to free.
return 0;
}
Check always that the number of free calls executed by your program has to be the same of the malloc calls you have made (before). A free call must free the memory allocated by one (and only one) call to malloc. You cannot free something that has not been acquired by malloc() (or calloc()) directly or indirectly. The same as it is bad use (but not necessary an error) to do a malloc that is not freed before the program ends (this is not true in non-hosted environments, e.g. embedded programs, in which the operating system doesn't deallocate the memory used by a program when it finishes, although)
By the way, the reason of your segmentation fault is precisely that you have made only two calls to malloc(), but you made 11 calls to free(). free() tries to free memory that malloc() has not allocated, or even worse, you don't own. Anyway, this drives you to Undefined Behaviour, which is something you don't desire in a program. In this case, you got a program crash.
Related
is there a simple one liner I can use in C to allocate arrays in (pointer of arrays)
This line creates 10 pointers of arrays
char *out[10];
I can't do this
char *out[100]=(char[10][100])malloc(sizeof(char)*10*100);
error: cast specifies array type
same error with
char *out[10]=(char*[10])malloc(sizeof(char)*10*100);
do I need to do it in loop like this
int main()
{
char *out[10];
int x=0;
while(x<10)
{
*(out+x)=malloc(sizeof(char)*100);// is this line correct?
x++;
}
*out[0]='x';
printf("%c\n",out[0][0]);
free(out);
return 0;
}
but this cause warning that
req.c:75:3: warning: attempt to free a non-heap object ‘out’ [-Wfree-nonheap-object]
75 | free(out);
so do I need to allocate and free each array in (array of pointers) in loop
Can't I do allocation and free arrays in array of pointer in one line instead of loop?
or is there anything thing in my loop wrong too
To allocate an array of pointers to strings, you need to do:
char** out = malloc(sizeof(char*[10]));
The whole point of using this form is that each pointer in that array of pointers can be allocated with individual size, as is common with strings. So it doesn't make sense to allocate such with a "one-liner", or you are using the wrong type for the task.
In case you don't need individual sizes but are rather looking for a char [10][100] 2D array with static size, then the correct way to allocate such is:
char (*out)[100] = malloc(sizeof(char[10][100]));
You can allocate the full array in one single step and have pointers inside that array:
char *out[10];
data = malloc(100); //sizeof(char) is 1 by definition
for (int x=0; x<10; x++) {
out[i] = data + x * 10;
}
*out[0] = 'x';
printf("%c\n",out[0][0]);
free(data); // you must free what has been allocated
int i;
char** out = (char**)malloc(sizeof(char*)*10);
for(i = 0; i<10;i++)
out[i] = (char*)malloc(sizeof(char)*100);
out[1][1] = 'a';
OR with same dimensions
#include <stdio.h>
#include <stdlib.h>
void main()
{
int r = 10, c = 100; //Taking number of Rows and Columns
char *ptr, count = 0, i;
ptr = (char*)malloc((r * c) * sizeof(char)); //Dynamically Allocating Memory
for (i = 0; i < r * c; i++)
{
ptr[i] = i + 1; //Giving value to the pointer and simultaneously printing it.
printf("%c ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
free(ptr);
}
I am trying to modify a 2D array from a void function.
#include <stdio.h>
#include <stdlib.h>
void try_by_reference(int **arr){
*arr = realloc(*arr, sizeof *arr * 2);
}
int main(int argc, char **argv){
// declare dynamic 2d-array and allocate memory
int (*arr)[2] = malloc(sizeof *arr * 10);
// fill array
for (int i=0; i<10; i++){
arr[i][0] = i;
arr[i][1] = i+10;
}
// declare and fill a simpler dynamic array
int *tarr = malloc(sizeof(int) * 10);
for (int i=0; i<10; i++)
tarr[i] = i*2;
try_by_reference(&tarr);
try_by_reference(&arr); <-- this gets warning
free(arr);
free(tarr);
return 0;
}
Compiler says:
warning: incompatible pointer types passing 'int (**)[2]' to parameter of type 'int **'
What am I doing wrong?
Thank you!
_"I am trying to modify a 2D array from a void function."_
Here are some tips, and fixes that will allow you to update memory to an array of two pointers to int. (see comment in-line with your code)
void try_by_reference(int **arr){
//always use a temporary variable to call realloc, otherwise if failed attempt - memory leak will occur
int *tmp = realloc(*arr, 2 * sizeof(*arr));//this effectively reduces memory from original 10, to 2 instances of int
if(!tmp)//always check return of realloc, if it fails free original memory and return
{
free(*arr);
//set pointer to NULL here to provide way to test before
//freeing later in process. (See 'Reference' below)
*arr = NULL;//to prevent problems in subsequent free calls
return;
}
else *arr = tmp;
}
int main(int argc, char **argv){
// declare dynamic 2d-array and allocate memory
int *arr[2] = {NULL, NULL};//this is an array of 2 pointers to int - each
//need to be allocated
//it will result in an array shaped as array[2][10]
//after following calls to malloc.
arr[0] = malloc(10*sizeof(arr[0]));//original provides memory for 10 instances of int
if(arr[0])
{
arr[1] = malloc(10*sizeof(arr[1]));
if(arr[1])
{
// fill array
//for (int i=0; i<10; i++){
for (int i=0; i<10; i++){
//arr[i][0] = i;
//arr[i][1] = i+10;
arr[0][i] = i;//switch indices
arr[1][i] = i+10;//switch indices
}
}
}
// declare and fill a simpler dynamic array
int *tarr = malloc(sizeof(int) * 10);
for (int i=0; i<10; i++)
tarr[i] = i*2;
try_by_reference(&tarr);
//try_by_reference(&arr); <-- this gets warning
//pass address of each pointer to memory, one at a time
try_by_reference(&(arr[0]));
try_by_reference(&(arr[1]));
//To prevent UB from calling free on an already freed pointer
//test before calling free.
if(arr[0]) free(arr[0]);//need to free each of two pointers to memory
if(arr[1] free(arr[1]);//...
if(tarr) free(tarr);
return 0;
}
Reference regarding why set pointer to NULL after freeing. If the call to realloc() fails, thus resulting in freeing the original pointer, setting the pointer == NULL provides a way to test before calling free() later in process, thus avoiding the potential of invoking undefined behavior (UB).
There are several ways to create varying shapes of nD arrays memory in C, some of them easier to update memory than the form int *arr[2]. But I stay with this form to illustrate specifically a way to update it. Although it requires more rigor to access elements, for a int[2][10] implemented by pointers, I prefer creating an int *arr = malloc(2*10*sizeof(*arr));. Observe the following examples for ease of use comparisons. (using a 2D like, but of different dimensions):
int arr1[3][6] = {{1,2,3,4,5,6},{7,8,9,10,11,12},{13,14,15,16,17,18}};
//same memory as
int arr2[18] = {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}};
knowing that *(arr1 + 2*6 + 5) == arr2[2][5] = 18;
*(arr1 + 0*6 + 4) == arr2[0][4] = 5;
*(arr1 + 1*6 + 0) == arr2[1][0] = 7;
// | | |_2nd index range 0 - 5
// | |_ constant -> sizeof(arr1[0]/arr1[0][0])
// |1st index range is from 0 - 2
The same is true for dynamic memory. int **arr1 and *arr2
int **arr1 //requires 7 calls to malloc/free
int *arr2 //requires 1 call to malloc/free
I need to create a program that plays the game Hex on a 14x14 board.
So I created, allocated and filled the board with '-' (our pattern for empty spaces).
When I try to print the board's coordinates, I don't always get '-' but some random characters.
Also, if I try to printf array[i][j] on the createBoard function after the line "board[i][j] = '-';" I get a segmentation fault right after it prints tab[8][0].
What is causing this and how can I fix it?
My code:
#include <stdio.h>
#include <stdlib.h>
char **createBoard()
{
/*Allocates a 14x14 matrix and fills it
*with '-' to create the board.*/
int i, j;
char **board;
board = malloc(14);
if (!board) exit(1);
for (i = 0; i < 14; i++){
board[i] = malloc(14);
if (!board[i]) exit (1);
for (j = 0; j < 14; j++)
board[i][j] = '-';
}
return board;
}
int main()
{
int i, j;
char **board = createBoard();
for (i = 0; i < 14; i++)
for (j = 0; j < 14; j++)
printf("tab[%d][%d]: %c\n",i, j, board[i][j]);
return 0;
}
For starters it is not clear why you don't want to declare an array instead of allocating dynamically numerous one-dimensional arrays.
As for the code then this memory allocation
board = malloc(14);
is invalid. You have to write
board = malloc( 14 * sizeof( char * ));
Also you should free all the allocated memory in the reverse order relative to its allocation before the program ends.
Take into account that it is always better to use named constants instead of magic numbers. At least you could write either
#define N 14
before main
or
const int N = 14.
and use the variable N everywhere where you are using magic number 14.
By the way according to the C Standard function main without parameters shall be declared like
int main( void )
The variable *board is a pointer, but you only allocate one byte for each array element, which should be
#define DIM 14
board = malloc(DIM * sizeof *board);
Following that up with the second allocation
board[i] = malloc(DIM * sizeof **board);
This also allows (a) that the dimension 14 is hard coded in only one place in the program and (b) the allocation will survive if you later make the board's element a different type, for example a struct, as the program develops.
I am trying to load two double numbers from input into a two-dimensional array that is dynamically reallocated by each user input.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int count;
double number1, number2, **numbers;
while (scanf("%lf,%lf", number1, number2) != EOF) {
count++;
numbers = (double**) realloc(numbers, count * 2 * sizeof (double));
if (numbers == NULL) {
exit(1);
}
numbers[count][0] = number1;
numbers[count][1] = number2;
}
return 0;
}
The program compiles without problems, but it fails every time I try to store a value in the array (it is likely a memory problem).
Can someone show me how to properly reallocate the two-dimensional array in my program?
You have a couple of problems.
You don't initialize numbers = 0; or count = 0 so you have an indeterminate value in the variable before you start the first realloc() call. That's bad news.
The more major problem is that you've misunderstood the memory allocation that's needed to simulate a 2D-array.
Your scanf() call is incorrect; you are not passing pointers to it.
ASCII Art
+---------+
| numbers |
+---------+
|
v
+------------+ +---------------+---------------+
| numbers[0] |---->| numbers[0][0] | numbers[0][1] |
+------------+ +---------------+---------------+
| numbers[1] |---->| numbers[1][0] | numbers[1][1] |
+------------+ +---------------+---------------+
| numbers[2] |---->| numbers[2][0] | numbers[2][1] |
+------------+ +---------------+---------------+
You actually need the pointer stored in numbers, the array of pointers, and the array of double. At the moment, you are not allocating the space for the array of pointers, and this is the cause of your troubles. The array of doubles can be contiguous or non-contiguous (that is, each row may be separately allocated, but within a row, the allocation must be contiguous, of course).
Working code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int count = 0;
double number1, number2;
double **numbers = 0;
while (scanf("%lf,%lf", &number1, &number2) != EOF)
{
numbers = (double **) realloc(numbers, (count + 1) * sizeof(*numbers));
if (numbers == NULL)
exit(1);
numbers[count] = (double *)malloc(2 * sizeof(double));
if (numbers[count] == 0)
exit(1);
numbers[count][0] = number1;
numbers[count][1] = number2;
count++;
}
for (int i = 0; i < count; i++)
printf("(%8.2f, %8.2f)\n", numbers[i][0], numbers[i][1]);
for (int i = 0; i < count; i++)
free(numbers[i]);
free(numbers);
return 0;
}
NB: This is still not good code. In particular, the increment-by-one-each-time mechanism in use is bad. The meme pointer = realloc(pointer, newsize); is bad too; you can't release the previously allocated memory if the allocation fails. You should use newptr = realloc(pointer, newsize); followed by a memory check before pointer = newptr;.
Input file:
12.34,23.45
34.56,45.67
56.78,67.89
78.90,89.01
Output data:
( 12.34, 23.45)
( 34.56, 45.67)
( 56.78, 67.89)
( 78.90, 89.01)
Not formally run under valgrind, but I'm confident it would be OK.
What is the best solution for saving inputs into array without knowing how many inputs I have to store ? Or maybe it is just this complicated in C compared to Java or PHP?
Except for the 'increment by one' part, this about the way it has to work in C, at least if you want to index into the result using two indexes: numbers[i][0] etc.
An alternative would be to allocate the space as you were doing (except not 'incrementing by one'), and then using an expression to index the array: double *numbers = ...; and numbers[i*2+0] and numbers[i*2+1] in your case, but in the more general case of an array with ncols columns, accessing row i and column j using numbers[i*ncols + j]. You trade the notational convenience of numbers[i][j] against the increased complication of memory allocation. (Note, too, that for this mechanism, the type of the array is double *numbers; instead of double **numbers; as it was in your code.)
The alternatives avoiding 'increment by one' typically use a doubling of the amount of space on each allocation. You can decide to do an initial allocation with malloc() and subsequently use realloc() to increase the space, or you can use just realloc() knowing that if the pointer passed in is NULL, then it will do the equivalent of malloc(). (In fact, realloc() is a complete memory allocation management package in one function; if you call it with size 0, it will free() the memory instead of allocating.) People debate whether (ab)using realloc() like that is a good idea or not. Since it is guaranteed by the C89/C90 and later versions of the C standard, it is safe enough, and it cuts out one function call, so I tend to use just realloc():
#include <stdio.h>
#include <stdlib.h>
static void free_numbers(double **array, size_t size)
{
for (size_t i = 0; i < size; i++)
free(array[i]);
free(array);
}
int main(void)
{
int count = 0;
double number1, number2;
double **numbers = 0;
double maxnum = 0;
while (scanf("%lf,%lf", &number1, &number2) != EOF)
{
if (count == maxnum)
{
size_t newnum = (maxnum + 2) * 2; /* 4, 12, 28, 60, ... */
double **newptr = (double **)realloc(numbers, newnum * sizeof(*numbers));
if (newptr == NULL)
{
free_numbers(numbers, count);
exit(1);
}
maxnum = newnum;
numbers = newptr;
}
numbers[count] = (double *)malloc(2 * sizeof(double));
if (numbers[count] == 0)
{
free_numbers(numbers, count);
exit(1);
}
numbers[count][0] = number1;
numbers[count][1] = number2;
count++;
}
for (int i = 0; i < count; i++)
printf("(%8.2f, %8.2f)\n", numbers[i][0], numbers[i][1]);
free_numbers(numbers, count);
return 0;
}
This code was checked with valgrind without problems; all code allocated was freed. Note the use of the function free_numbers() to release the memory in the error paths. That's not critical when it is running in a main() function like here, but is definitely important when the work is done in a function that may be used by many programs.
You're incrementing the count variable too early. The first value it will index into the array will be one, however array indexing starts at zero.
Having the count++ after assigning the new values and initializing count to zero should work.
However, read the comments other users have posted, you really want a nicer approach to this problem.
#include <stdio.h>
#include <stdlib.h>
void agregar_int(int **,int);
void agregar_char(char **,int);
char **tz=NULL;
int **tr=0;
int a;
int main(void){
a=2;
for (a=1;a<100;a++)
{
agregar_int(tr,a);
}
for (a=1;a<100;a++)
{
agregar_char(tz,a);
}
}
agregar_int (int **tr,int a)
{
printf ("%d----------------------------------------------\n",a);
tr = (int**) realloc (tr, (a+1) * sizeof(*tr));
tr[a] = (int *) malloc (5 * sizeof(int));
tr[a][0]=a; tr[a][1]=a;tr[a][2]=a;tr[a][3]=a;tr[a][4]=a;
printf("%d \t %d \t %d \t %d \t %d \n",tr[a][0],tr[a][1],tr[a][2],tr[a][3],tr[a][4]);
}
agregar_char (char **tz,int a)
{
printf ("%d----------------------------------------------\n",a);
tz = (char**) realloc (tz, (a+1) * sizeof(*tz));
tz[a] = (char *) malloc (7 * sizeof(char));
tz[a][0]='E'; tz[a][1]='s';tz[a][2]='t';tz[a][3]='e';tz[a][4]='b',tz[a][5]='a',tz[a][6]='n';
printf("%c%c%c%c%c%c%c \n",tz[a][0],tz[a][1],tz[a][2],tz[a][3],tz[a][4],tz[a][5],tz[a][6]);
}
Hi friends I am trying to assigned elements from arr2[] to a pointer p_arr and then trying to print from p_arr...
I think something is messing up, not getting expected values...
#include <stdio.h>
#include <stdlib.h>
#define MAX_ONE 9
#define MAX_TWO 9
int arr1[] = {10,20,30,40,50,67,23,47,79};
int arr2[] = {5,15,25,35,45,34,45,67,89};
int *main_arr[] = {arr1,arr2};
int main()
{
int i;
int *p_arr2;
p_arr2 = (int *)malloc(sizeof(int)*2);
for(i=0;i<MAX_ONE;i++)
{
*p_arr2++ = arr2[i];
arr2[i] = arr1[i];
}
for(i=0;i<MAX_TWO;i++)
{
printf("%d\n",*(p_arr2));
p_arr2++;
//printf("%d\t",arr2[i]);
}
system("PAUSE");
return 0;
}
p_arr2 = (int *)malloc(sizeof(int)*2);
You allocated only enough memory for 2 integers and you are trying to store MAX_ONE in this array. This results in writing beyond the allocated memory block and an Undefined behavior.
You need to allocated enough memory to store MAX_ONE elements.
p_arr2 = malloc(sizeof(int)*MAX_ONE);
^^^^^^^^^
Also, you do not need to cast the return type of malloc in C.
In addition to the allocation issues mentioned, before you start the print loop, you don't reset p_arr2 to point at the start of the array. So you're printing from uninitialized memory.
Try this. Also always try to free dynamically allocated memory
p_arr2 = malloc(sizeof(int)*MAX_ONE);
for(i=0;i<MAX_ONE;i++)
{
p_arr2[i] = arr2[i];
arr2[i] = arr1[i];
}
for(i=0;i<MAX_TWO;i++)
{
printf("%d\n",*(p_arr2 + i));;
//printf("%d\t",arr2[i]);
}
free (p_arr2);