0

I'm trying to declare arrays with a variable size, given by user input.

So far I have something like this:

typedef struct _object{   
    int rowsAmount;  
    int columsAmount;
    int* rows;
    int* colums;
} object;

object* newObject(int ra, int ca){
    object* o = malloc(sizeof(object));
    o->rowsAmount = ra;
    o->columsAmount = ca;
    o->rows = [ra];    
    o->colums = [ca];
    return o;
}

int main(){
    newObject(3,4);
}

I expected this wouldn't work, but I want something like this, and I don't know how to do it.

7
  • do you want a 2d array of 2x 1d arrays? Commented Apr 22, 2013 at 10:01
  • 1
    Does it even compile!? What, pray tell, is this: m->rows = [ra];? Commented Apr 22, 2013 at 10:03
  • @LefterisE I'm just trying to learn c, this is only about the setting the size. I just happened to try it with 2 arrays. Commented Apr 22, 2013 at 10:10
  • @StoryTeller, I knew that wouldn't work, It's just the only way I could think of to show what I'm trying to do. Commented Apr 22, 2013 at 10:11
  • 1
    @Yananas Your function newObject() is expected to return a value of type object* but it is clearly not doing so!! Commented Apr 22, 2013 at 10:14

6 Answers 6

3

It looks like you're basically implementing a dynamic Matrix object here. You want something like:

typedef struct _object{   
    int rowsAmount;  
    int columsAmount;
    int* matrix;
    int** rows;
} object;

object* newObject(int ra, int ca){
    object* o = malloc(sizeof(object));
    o->rowsAmount = ra;
    o->columsAmount = ca;
    o->matrix = malloc(ra * ca * sizeof(int));
    o->rows = malloc(ra * sizeof(int*));
    for (size_t i = 0; i != ra; ++i) o->rows[i] = o->matrix + (i * ca);
    return o;
}

You should also create a destructor function destroyObject, which similarly frees all the memory allocated for o and o->matrix.

Edit:

However, your comment that:

"I'm just trying to learn c, this is only about the setting the size. I just happened to try it with 2 arrays"

...makes this question somewhat confusing, because it indicates you are not, in fact, trying to create a matrix (2D array) despite your use of "row"/"column" terminology here, but that you simply want to understand how to dynamically allocate arrays in C.

If that's the case, an array in C is dynamically allocated using a pointer variable and malloc:

size_t array_size = 10; /* can be provided by user input */
int* array = malloc(sizeof(int) * array_size);

And then later, the dynamically-allocated array must be freed once you are finished working with it:

free(array);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that makes sense. I am going to make this into a matrix like thing later when I understand stuff, so it really was helpful.
0

To dynamically allocate a 2d array of data in C:

  • Allocate the memory for the entire data. That memory is pointed to by arrayData.
  • Allocate an 1D Array of pointers one for each row
  • Point those pointers to the memory address corresponding each row

Code:

int *arrayData = malloc(sizeof(int) * rows * columns);
int **array = malloc(sizeof(int*) * rows);
for(int i=0; i < rows;++i){
   array[i] = arrayData + i * columns;
}

You can now access the memory as array[row][col].

Comments

0

You can create a array with size input from user with out a structure.

int *array1;
int size;
// get input from user
array1 = malloc(sizeof(int)*size);
// do your stuff
free(array1);

if you want a 2D array,

int **array2;
int row, col;
int i;
array2 = malloc(sizeof(int*)*row);
for(i=0;i<row;++i)
    array2[i] = malloc(sizeof(int)*col);
//use the array
for(i=0;i<row;++i)
    free(array2[i]);
free(array2);

if you really need a structure array, then allocate memory for it in your newObject() function

typedef struct _object{   
    int rowsAmount;  
    int columsAmount;
    int** array;
    //int* colums;
} object;

object* newObject(int ra, int ca){
    int i;
    object* o = malloc(sizeof(object));
    o->rowsAmount = ra;
    o->columsAmount = ca;
    o->array = malloc(sizeof(int*)*ra);    
    for(i=0;i<ra;i++)
        o-<array[i]=malloc(sizeof(int)*ca);
    return o;
}

int main(){
    newObject(3,4);
}

Comments

0

I think that quite often people use dynamic memory allocation when scoped variables can be used instead. For example, array sized from user's input can be allocated on stack without using malloc/free:

int array_size;
scanf("%d", &array_size);
if (array_size > 0) {
    /* Allocate array on stack */
    float array[array_size];

    /* ... do smth with array ... */
}
/* Out of scope, no need to free array */

Of course if your data block is huge, heap memory is a must, but for small allocations scopes are just fine.

Comments

-1

Easiest way is to use boost::multi_array Not only will you get any number of dimensions, it's also stored very efficiently as a single contiguous block of memory rather than n dimensional array.

CPU's are designed to traverse arrays quickly, and you could potentially utilise caching/prefetch/pipelining features of the compiler using this.

Eg

// 2 dimensions
int xDim;
int yDim;
cin >> xDim; // From user..
cin >> yDim;
// Initialise array
boost::multi_array<int,2> my2dgrid(boost::extents[xDim][yDim]);
// Iterate through rows/colums
for(int j = 0 ; j < yDim-1; j++) { // Row traversal
for(int i = 0 ; i < xDim-1; i++) { // Column traversal
   int value = grid[j][i]; // Get a value
   grid[j][i] = 123; // set a value
   // Do something...
}

1 Comment

The OP did not specify C++
-1
#include <stdio.h>
#include <stdlib.h>

typedef struct _object{   
    int rowsAmount;  
    int columsAmount;
    int **rows;
//  int* colums;
} object;

object* newObject(int ra, int ca){
    int r;
    object* o = malloc(sizeof(object));
    o->rowsAmount = ra;
    o->columsAmount = ca;
    o->rows = (int **)malloc(ra*sizeof(int *));
    for(r=0;r<ra;++r)
        o->rows[r] = (int*)malloc(ca*sizeof(int));
    return o;
}

int main(){
    object *obj= newObject(3,4);
    obj->rows[2][3]=5;
    return 0;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.