0

I am making a C function to integrate into Python that basically creates a two-dimensional array of chars (each row has constant, known length), reads some data into it, builds a numpy array from it, and returns it to the calling function in Python. I'm not an expert with C, but I believe that in order to preserve the array in memory after exiting the function where it was created, I need to allocate it on the heap with malloc. So I am trying this line:

//rowSize and interleaved are both integers; bytesPerTable is equal to rowSize * interleaved
char arrs[interleaved][rowSize] = (char **)malloc(bytesPerTable * sizeof(char));

Which gives me the compiler error

error: variable-sized object may not be initialized

I'm not sure how to make this work. I want to allocate a block of memory that is the size I need (bytesPerTable) and then organize it into the required two-dimensional array. If I simply declare

char arrs[interleaved][rowSize];

Then it works, but it's on the stack rather than the heap. Can anyone help?

3 Answers 3

2

Do it like this

char (*arrs)[rowSize] = malloc(bytesPerTable);

arrays can't be assigned to, pointers and arrays are really different kinds of objects.

Also:

  • don't cast the return of malloc
  • sizeof(char) is 1 by definition
Sign up to request clarification or add additional context in comments.

8 Comments

Are you sure it's portable to assume sizeof(char) to always be 1? AFAIK there's no guarantee about this.
@Tudor, as I said it is even defined to be like this. The sizeof operator measures the size of an object in terms of multiples of char that fit into it. Your are perhaps mixing this up with the number of bits in a char. Although it is 8 in any architecture that you are likely to encounter, theoretically it could be larger. But sizeof(char) is always 1.
Yes, it's guaranteed to be 1. From the C standard When applied to an operand that has type char, unsigned char, or signed char,(or a qualified version thereof) the result is 1.
@Tudor: yes, sizeof(char) is guaranteed to be 1.
@JensGustedt: shouldn't the argument to malloc be sizeof *arrs * interleaved?
|
2

What you need is this:

char** arrs = (char **)malloc(interleaved * sizeof(char*));
for(i = 0; i < bytesPerTable; i++)
    arrs[i] = (char*)malloc(rowSize * sizeof(char));

This: char arrs[interleaved][rowSize]; is just a typical stack allocation.

13 Comments

yep, should iterate through first level pointers to malloc each
an emulated arrray was not what the OP has asked for, and which probably is not very much appropriate to pass to python.
@Jens Gustedt: Upon re-reading his question I'm a bit confused. He does mention he wants rows to be of constant size, yet he also used (char**) on the right side of the assignment...
@Tudor as he seems to be coming from a python background this char** there is probably just an artefact of him trying to make this work.
The way Jens allocated it is the preferred way, Python or not, because it allocates memory adjacently on the heap, making it 100% compatible with statically allocated arrays and C library functions. I never understood why people keep insisting on the pointer-to-pointer version.
|
0

You need to alloc it to a pointer, then you can cast it as an array.

1 Comment

Right, was getting confused with structs. So I guess memcpy from the pointer to the array then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.