I need to create character array at runtime because question input goes like this:
1. The first line contains , N the number of strings.
2. The next N lines each contain a string.
I tried creating 2-D array but it didn't work.
int main() {
int n,count;
scanf("%d",&n);
for(int i=0; i<n; i++){
char* arr[i]= char*(malloc(sizeof(char)));
}
return 0;
}
Do something like this:
#define STRINGSIZE 30;
int main() {
int n,count;
scanf("%d",&n);
char **arr;
arr = malloc(sizeof(char*) * n);
for(int i=0; i<n; i++){
arr[i]= malloc(sizeof(char) * STRINGSIZE);
}
return 0;
}
Explanation:
In C, you have pointers to access array. For a multidimensional array with variable lengths, its common to have pointer to pointers. So char **arr; arr = malloc(sizeof(char*) * n); means that you're creating an array of pointers to char. Then you need to call malloc for each of these pointers to allocate memory for each string.
Of course, you do not need to use a constant for string sizes. You can use a variable instead, and you can use different sizes for each string.
Note:
To avoid problems in the future if you want to change the array to an int array instead, do like this and you do not have to worry about changing on more places:
char **arr;
arr = malloc((sizeof a[0]) * n);
for(int i=0; i<n; i++){
arr[i]= malloc((sizeof a[0][0]) * STRINGSIZE);
}
Also, do not cast malloc
And as kkk pointed out in the comments. Check return values.
arr = malloc(sizeof(char*) * n);
if (NULL == arr) {
perror("Could not allocate memory");
exit(EXIT_FAILURE);
}
Related
Can I use
size_t m, n;
scanf ("%zu%zu", &m, &n);
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
to create a dynamic 2D array in C, whose size of rows and columns can be modified by function realloc during runtime?
Also you can use pointer-to-pointer-to-int and alloc first array for "pointers to lines" and then init all items by allocating memory for "arrays of int".
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t m, n;
scanf("%zu%zu", &m, &n);
int **a = (int **)calloc(m, sizeof(int*));
size_t i, j;
for (i = 0; i < m; i++) {
a[i] = (int *)calloc(n, sizeof(int));
}
/// Work with array
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
a[i][j] = i+j;
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
Such approach allows to make realloc later
This record
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
is correct provided that the compiler supports variable length arrays.
It may be written also like
int (*a)[n] = calloc ( 1, sizeof ( int[m][n] ) );
On the other hand, there is a problem when you will use realloc and the number of columns must be changed. This can result in losing elements in the array in its last row because C memory management functions know nothing about types of objects for which the memory is allocated. They just allocate extents of memory of required sizes.
Otherwise if the compiler does not support variable length arrays you will need to allocate array of pointers and for each pointer an array of integers. This approach is more flexible in sense that you can reallocate separately columns and rows.
Can I create a dynamic 2D array in C like this?
int (*a)[n] = (int (*)[n])calloc (m * n, sizeof (int));
Yes.
Cleaner as int (*a)[n] = calloc(m, sizeof a[0]);
Can I use int (*a)[n] = .... to create a dynamic 2D array in C, whose size of rows and columns can be modified by function realloc during runtime?
No. Once an array size of a is defined, (n in this case), the size can not change.
Instead consider allocating an array of arrays
// Error checking omitted for brevity
int **a2 = malloc(sizeof a2 * rows);
for (r = 0; r < rows; r++) {
a2[r] = malloc(sizeof a2[0] * cols);
}
I have 2D array allocated dynamically using this method:
How do we allocate a 2-D array using One malloc statement
#include <stddef.h>
int main() {
size_t i;
unsigned int nrows=2;
unsigned int ncolumns=3;
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
int * const data = array + nrows;
for(i = 0; i < nrows; i++) {
array[i] = data + i * ncolumns;
printf("%x\n", data + (i * 3));
}
}
I understand that array[0] points to 1st 1D array (of 2D array) and array[1] points to 2nd 1D array, but now how to initialize (and access) others member of this 2D array, for instance a[0][1] can be access like?
array[0] + (char *)1
It would great, if I may ask for some graphical view of it.
The main problem is that you read a lot of harmful answers in that other post. You are making everything needlessly slow and complicated. Instead study Correctly allocating multi-dimensional arrays (which has the requested graphical view as "ASCII art").
Fixed code printing some hex data as example:
#include <stdlib.h> // include this!
#include <stdio.h>
int main()
{
// memory in C is laid out in rows, so ideally use rows as inner index
unsigned int col=4;
unsigned int row=8;
int (*array)[row] = malloc(sizeof(int[col][row]));
int count=0; // some data
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
array[i][j] = count++;
printf("%.2X ", array[i][j]);
}
printf("\n");
}
free(array); // call this!
}
I'm trying to create a 2D array for storing names (with max 50 characters each). I have written a code, but it isn't working properly, where's the problem? (I can do this with statics arrays, however at the beginning my program won't know how many names I will want to store in the array). Here's my code:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n=5;
int size=51;
char *a_name=(char*)malloc(n*size*sizeof(char));
for(int i=0;i<n;i++){
scanf("%s",&a_name[i]);
}
for(int i=0;i<=n;i++){
printf("%s\n",a_name[i]);
}
return 0;
}
What you need is not an array of char but an array of char *.
Try this:
int n = 5, size = 51;
char **name_array = (char **)malloc(sizeof(char *) * n);
for (int i = 0; i < n; ++i) {
name_array[i] = (char *)malloc(sizeof(char) * size);
// You may initialize the array first.
scanf("%s\n", name_array[i]);
}
Remember to release the memory when you no longer need the names.
My program is getting segmentation fault if I allocate function as 1D array and then pass it to function. It is built for 2d array. Problem is, that I can't find out how to allocate 2d array and how to pass it correctly into function. Hope all is explained clearly. If you know what is wrong please try to lead me on correct way to fix it. Many thanks. Here is code:
int main()
{
int i, j, size;
scanf("%d", &size);
int *a;
//here i try to allocate it as 2d array
*a = (int *)malloc(size * sizeof(int));
for (i=0; i<size; i++)
{
a[i] = (int *)malloc(size * sizeof(int));
}
//here i scan value to 2d array
for (i = 0; i < size; i++)
for (j = 0; j < size; j++){
scanf("%d", &a[i][j]); }
//here i pass array and size of it into function
if (is_magic(a,size))
function header looks like:
int is_magic(int **a, int n)
This doesn't work:
*a = (int *)malloc(size * sizeof(int));
Because a has type int * so *a has type int, so it doesn't make sense to assign a pointer to that. You're also attempting to dereference a pointer which has not been initialized yet, invoking undefined behavior.
You need to define a as an int **:
int **a;
And assign to it directly on the first allocation, using sizeof(int *) for the element size:
a = malloc(size * sizeof(int *));
Note also that you shouldn't cast the return value of malloc.
Scanning 2D array ? For that you need to take a as of int** type not just int* type. For e.g
int **a = malloc(NUM_OF_ROW * sizeof(int*)); /* allocate memory dynamically for n rows */
And then allocate memory for each row for e.g
for (i=0; i<size; i++){
a[i] = malloc(NUM_OF_COLUMN * sizeof(int)); /* in each row how many column, allocate that much memory dynamically */
}
I was wondering how to properly use scanf to fill out a multidimensional array.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int n; //number of rounds
int* sArray; //multidimensional array that holds the scores of both players
int i;
scanf("%d", &n);
sArray = (int*) calloc (n * 2, sizeof(int));
for(i=0; i<n; i++) {
scanf("%d %d", &sArray[i][1], &sArray[i][2]);
}
return 0;
}
It gives me an error, "Subscripted value is not an array, pointer, or vector." Any help would be much appreciated!
A two dimentional array is defined as follows: int sArray[N][M], but since you wanted to work with the dynamic memory I offer you to take a look at a pointer to pointer at int:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int **sArray;
sArray = (int **)malloc(n * sizeof(int *));
int i;
for(i = 0; i < n; i++)
{
sArray[i] = (int *)malloc(2 * sizeof(int));
scanf("%d %d", &sArray[i][1], &sArray[i][2]);
}
return 0;
}
Don't forget to clean-up after you are done with the array.
As mentioned in the commentaries, You don't need to cast the result of malloc if you work with pure c. I did this because my c++ compiler refused to compile it without this cast.
You might need to check errors during a dynamic allocation of the array. Read more here
There are already a lot of good answers here on how to define your dynamic 2D array. But this variant was not yet mentionned, so I put it for the records.
As the last dimension of your array is fixed, you could define your 2D array as follows:
int (*sArray)[2]; //multidimensional array that holds the scores of both players
...
sArray = (int(*)[2]) calloc (n, sizeof(int)*2); // self explaining
In this way, all the elements will be stored contiguously (each n element of the allocated array, is 2 contiguous integers), without the need for an array to arrays.
The rest of your code remains identical. Except that you shoud address sArray[i][0] and ..[1] instead of [1] and [2] and free memory at the end. In C array indexing starts always from 0 and goes to size-1.
Of course, this approach is strictly limited to 2D arrays where the last dimension is fixed.
Live demo with addressing
Usually to fill a bidimensional array you will use two nested for loops.
For example :
int array[2][3] = {0};
for (i = 0; i < 2; i++)
for (k = 0; k < 3; k++)
scanf("%d", &array [i][k]);
You could do this too:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int n; //number of rounds
int** sArray = malloc(2 * sizeof(int*)); //multidimensional array that holds the scores of both players
scanf("%d", &n);
sArray[0] = (int*)calloc(n , sizeof(int));
sArray[1] = (int*)calloc(n , sizeof(int));
int i;
for (i = 0; i < n; i++) {
scanf("%d %d", &sArray[0][i], &sArray[1][i]);
}
free(sArray[0]);
free(sArray[1]);
free(sArray);
return 0;
}