Create a 2d character array in c - c

I want to create a 2d character array in C just like this one in php :
$matrix = array(
array('$','#','*','%','&','#','#','#','#','#'),
array('%','$','#','%','#','%','#','*','&','*'),
array('#','*','&','*','#','#','#','&','%','#'),
array('%','#','*','$','%','&','#','*','#','&'),
array('$','*','&','&','&','#','#','%','*','*'),
array('#','#','#','#','&','%','*','$','#','#'),
array('&','$','$','#','#','#','#','$','%','*'),
array('#','$','$','*','&','$','#','*','#','*'),
array('%','$','*','#','&','#','&','#','#','#'),
array('#','#','%','*','#','&','#','$','%','#')
);
I tried writing up this code :
int size = 10;
char matrix[size][size] = {
{'$','#','*','%','&','#','#','#','#','#'},
{'%','$','#','%','#','%','#','*','&','*'},
{'#','*','&','*','#','#','#','&','%','#'},
{'%','#','*','$','%','&','#','*','#','&'},
{'$','*','&','&','&','#','#','%','*','*'},
{'#','#','#','#','&','%','*','$','#','#'},
{'&','$','$','#','#','#','#','$','%','*'},
{'#','$','$','*','&','$','#','*','#','*'},
{'%','$','*','#','&','#','&','#','#','#'},
{'#','#','%','*','#','&','#','$','%','#'}
};
I am very new to c so i don't really know the concept of 2d arrays in c. But for some reason the above code is giving error. Please help.

This is because C compiler thinks that you are trying to initialize an array of length determined at runtime, even though you supply the size 10 at compile time.
Replacing int size= 10 with #define SIZE 10 will fix this problem:
#define SIZE 10
...
char matrix[SIZE][SIZE] = {
{'$','#','*','%','&','#','#','#','#','#'},
{'%','$','#','%','#','%','#','*','&','*'},
{'#','*','&','*','#','#','#','&','%','#'},
{'%','#','*','$','%','&','#','*','#','&'},
{'$','*','&','&','&','#','#','%','*','*'},
{'#','#','#','#','&','%','*','$','#','#'},
{'&','$','$','#','#','#','#','$','%','*'},
{'#','$','$','*','&','$','#','*','#','*'},
{'%','$','*','#','&','#','&','#','#','#'},
{'#','#','%','*','#','&','#','$','%','#'}
};
Demo.

In C99 there is a variable length array, so you can do that, but not all compilers support vla and C99 standard (#Jonathan Leffler but still can not initialize array).
So the solution is to give computer information about size of array before compilation. So you can define size with macros
#define size 10
Or to create array dynamically on heap using malloc (and other memory allocating functions)
Or to create array dynamically on stack using alloca and malloca
Also on some compilers I found that const variables can be used to do that, but that is rare (found on borland) and not standard.
If you initialize array, then you can omit dimensions. For example
int a[] = {1, 2, 3};
int b[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };

int size = 10;
char matrix[size][size];
memcpy(&matrix[0][0],
"$#*%&#####"
"%$#%#%#*&*"
"#*&*###&%#"
"%#*$%&#*#&"
"$*&&&##%**"
"####&%*$##"
"&$$####$%*"
"#$$*&$#*#*"
"%$*#&#&###"
"##%*#&#$%#", size*size);

Assuming a 10x10 char array:
char **matrix = malloc(sizeof(char*)*10);
int i, len = 10;
for(i = 0; i < len; i++)
matrix[i] = (char *)malloc(11) // the 11th one is for the null '\0' character (you can ignore it if you like)
Now you can fill the char array locations as you like:
// for example row 1 column 1
matrix[0][0] = '$';
that should help.
After you're done, make sure you use "free" to free the memory allocated.

Related

How to initialize already defined flexible length array in C?

Consider the code:
#include <stdio.h>
int a[] = { 1, 2, 3 };
int b[];
int main() {
b = { 4, 5, 6 };
return 0;
}
This of course is illegal.
main.c:7:9: error: expected expression before '{' token
7 | b = { 4, 5, 6 };
| ^
I need to initialize array b in a function. How to do that?
I know one way, but it's... IDK, really?
#include <stdio.h>
int a[] = { 1, 2, 3 };
int b[3];
int main() {
b[0] = 4;
b[1] = 5;
b[2] = 6;
return 0;
}
Is it the only way of doing that?
EDIT:
It's very hard to explain my intent.
Let's say I define items in code. Right? Is that clear? In code, means - it's static, not dynamic. Not runtime. Not "variable length". Let's say it will be 5 items, right? So why don't I just say 5 and set the fixed length to 5?
The reason for this is, I don't have to write:
int a[5] = { 1, 2, 3, 4, 5 };
```c
but instead I can write
```c
int a[] = { 1, 2, 3, 4, 5 };
That saves me the redundant step of counting my items manually, because the compiler counts the items for me. It also allocates the memory on stack for them for me. No need to call malloc.
And here goes the hard to explain part:
Imagine instead of 1, 2, 3, 4 I have structures. They are not numbered, they contain various data types.
Imagine, that later in time I add an additional item to my array, because it will become necessary at a certain point of the project development. To be absolutely clear: this is not by any means dynamic. I will never need a single item more during the runtime. It will be added to the code and committed to Git. And it will stay there, maybe to the end of the program's life.
Imagine I add the item, but I forget to update the items count. It's a super common bug.
The whole point for me is to learn, whether a syntax in C exists allowing to omit the item count by initializing array inside a function. Now I suspect - it is not possible. I can either make such initialization when defining a variable, but not when assigning to the variable, even if it's the only assignment made to that variable.
I'd avoid to allocate more bytes than necessary, also performing more operations than necessary because it's for embedded and I really aim to cut that kind of costs. I also learn how to do the things the correct way, even if I technically could waste some resources.
Additional problem with my real code is some data for the items is not available before a function is called.
So my temporary solution is just to specify the array length. And then remember to update it when I add or remove items DURING DEVELOPMENT. That should work. If it's the correct way of doing that, than it's fine and I'm done. If not, I'd be happy to learn how to do it a better way.
The proper term is variable length array. This is an array whose size is determined by a non-constant expression. Its size is set at execution time when program execution reaches the definition of the array. (“Flexible” is used in the term flexible array member, which is an array that is the last member of a structure and that adapts to the memory allocated for the structure.)
The size of a variable length array must be given where the array is defined, as with int b[n];. You cannot leave the size incomplete, as with int b[];, and specify it later.
C has no grammar for assigning directly to an array. You can assign values to individual elements, and a method for specifying values in aggregate is to use memcpy to copy them from another array, which can be a compound literal:
#include <stdio.h>
#include <string.h>
int main(void)
{
int n = 3;
int b[n];
memcpy(b, (int []) { 4, 5, 6 }, sizeof b);
for (int i = 0; i < 3; ++i)
printf("b[%d] = %d.\n", i, b[i]);
}
The first thing that's wrong is
int b[];
This makes no sense. gcc treats this as the following
int b[1];
This is most definitely wrong. You want
int *b;
Cloning a would be done as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t size = sizeof( a );
b = malloc( size );
if ( !b ) {
perror( "malloc" );
exit( 1 );
}
memcpy( b, a, size );
Don't forget to free( b );.
Imagine I add the item, but I forget to update the items count.
I think what you're getting at is that you need the size of the array, but you don't want to hardcode it.
No problem. Use this:
int a[] = { 5, 6, 7 };
size_t n = sizeof( a ) / sizeof( *a );
Then you can do stuff like this:
for ( size_t i = 0; i < n ; ++i )
do_this( a[i] );
or
do_that( a, n );
At no point was 3 mentioned, so the code keep working even if you change the initialization of a to the following:
int a[] = { 5, 6, 7, 8 };
The whole point for me is to learn, whether a syntax in C exists allowing to omit the item count by initializing array inside a function
There's nothing special about arrays in functions. Just like outside of functions, you will need to provide a size (int b[...];) or an initializer (int b[] = ...;). Without this, the program wouldn't know how much space to allocate.
But while you say this is the point, it's obviously not. You appear to want to ensure that two arrays are the same size, as you make clear in your following paragraph.
I'd avoid to allocate more bytes than necessary, also performing more operations than necessary because it's for embedded and I really aim to cut that kind of costs. I also learn how to do the things the correct way, even if I technically could waste some resources.
If the array fits on the stack, you can use the following to allocate it on the stack instead of using malloc.
void do_that( int *a, size_t n ) {
int b[n];
...
}
These are called variable length arrays, and it was an addition to C99. (They are variable-length in the sense that every instance of an array created by this code can have a different length. But the created arrays are fixed in size like every C array.)
Imagine I add the item, but I forget to update the items count. It's a super common bug.
The crux of this problem is that you should not code the items count as some constant. Instead use code to calculate to items count value or simply use the size of b[].
#include <assert.h>
#include <string.h>
// Array b exist _someplace_ of some size
void assign_b() {
// Form the initialization list.
same_type_as_b_element b_values[] = { 8, 6, 7, 5, 3, 0, 9 };
// Same size?
static_assert(sizeof b == sizeof b_values), "Mis-matched sizes in b[]");
// Copy to b
memcpy(b, b_values, sizeof b);
}

Can someone please explain this. It deals with malloc and global array in C

If I'm trying to create a global array to hold an arbitrary number of integers in this case 2 ints. How is it possible that I can assign more numbers to it if I only allocate enough space for just two integers.
int *globalarray;
int main(int argc, char *argv[]) {
int size = 2;
globalarray = malloc(size * sizeof(globalarray[0]));
// How is it possible to initialize this array pass
// the two location that I allocated.
for (size_t i = 0; i < 10; i++) {
globalarray[i] = i;
}
for (size_t i = 0; i < 10; i++) {
printf("%d ", globalarray[i]);
}
printf("%s\n", "");
int arrayLength = sizeof(*globalarray)/sizeof(globalarray[0]);
printf("Array Length: %d\n", arrayLength);
}
When I run this it gives me
0 1 2 3 4 5 6 7 8 9
Array Length: 1
So I wanted to know if someone could clarify this for me.
(1) Am I creating the global array correctly?
(2) Why is the array length 1? When I feel that it should be 2 since I malloced the pointer for 2.
And background info on why I want to know this is because I want to create a global array (shared array) so that threads can later access the array and change the values.
How is it possible to initialize this array pass the two location that I allocated.
Short answer: This is undefined behaviour and anything can happen, also the appearance that it worked.
Long answer: You can only initialize the memory you've allocated, it
doesn't matter that the variable is a global variable. C doesn't prevent you from
stepping out of bounds, but if you do, then you get undefined behaviour and anything can happen
(it can "work" but it also can crash immediately or it can crash later).
So if you know that you need 10 ints, then allocate memory for 10 int.
globalarray = malloc(10 * sizeof *globalarray);
if(globalarray == NULL)
{
// error handling
}
And if you later need more, let's say 15, then you can use realloc to increase
the memory allocation:
globalarray = malloc(10 * sizeof *globalarray);
if(globalarray == NULL)
{
// error handling
// do not contiue
}
....
// needs more space
int *tmp = realloc(globalarray, 15 * sizeof *globalarray);
if(tmp == NULL)
{
// error handling
// globalarray still points to the previously allocated
// memory
// do not continue
}
globalarray = tmp;
Am I creating the global array correctly?
Yes and no. It is syntactically correct, but semantically it is not, because you are
allocating space for only 2 ints, but it's clear from the next lines that
you need 10 ints.
Why is the array length 1? When I feel that it should be 2 since I malloced the pointer for 2.
That's because
sizeof(*globalarray)/sizeof(globalarray[0]);
only works with arrays, not pointers. Note also that you are using it wrong in
two ways:
The correct formula is sizeof(globalarray) / sizeof(globalarray[0])
This only works for arrays, not pointers (see below)
We sometimes use the term array as a visual representation when we do stuff
like
int *arr = malloc(size * sizeof *arr)
but arr (and globalarray) are not arrays,
they are pointers. sizeof returns the amount in bytes that the
expression/variable needs. In your case *globalarray has type int and
globalarray[0] has also type int. So you are doing sizeof(int)/sizeof(int)
which is obviously 1.
Like I said, this only works for arrays, for example, this is correct
// not that arr here is not an array
int arr[] = { 1, 2, 3, 4 };
size_t len = sizeof arr / sizeof arr[0]; // returns 4
but this is incorrect:
int *ptr = malloc(4 * sizeof *ptr);
size_t len = sizeof ptr / sizeof ptr[0]; // this is wrong
because sizeof ptr does not returns the total amount of allocated
bytes, it returns the amount of bytes that a pointer needs to be stored in memory. When you are dealing with
pointers, you have to have a separate variable that holds the size.
C does not prevent you from writing outside allocated memory. When coding in C it is of the utmost importance that you manage your memory properly.
For your second question, this is how you would want to allocate your buffer:
globalarray = malloc(sizeof(int) * size);
And if you are on an older version of C than c11:
globalarray = (int*) malloc(sizeof(int) * size);

Find the Array length inside Function

Based on This Question Calculate Length of Array in C by Using Function i really need an explanation.
Let's say we have an Array like this:
int arr[] = {1,2,3};
here arr has the length 3, so passing into a Function will decay to Pointer and we lose track of its Length.
What happens if we Null terminate this array using '\0' like this:
int arr[] = {1,2,3,'\0'};
And pass it to a function like this:
void foo(int *arr){
int length = 0;
while(arr[length] != '\0'){
length++;
}
printf("Length = %d\n",length);
}
Is this ok?
I wrote the following code:
#include<stdio.h>
void foo(int *arr);
int main(void){
int arr1[] = {10,'\0'};
int arr2[] = {12,44,'\0'};
int arr3[] = {87,1,71,'\0'};
int arr4[] = {120,15,31,82,'\0'};
int arr5[] = {28,49,16,33,11,'\0'};
int arr6[] = {19,184,90,52,38,77,'\0'};
int arr7[] = {2,17,23,41,61,78,104,'\0'};
int arr8[] = {16,92,11,35,52,118,79,44,'\0'};
int arr9[] = {20,44,33,75,49,36,9,2,11,'\0'};
int arr10[] = {92,145,24,61,99,145,172,255,300,10,'\0'};
foo(arr1);
foo(arr2);
foo(arr3);
foo(arr4);
foo(arr5);
foo(arr6);
foo(arr7);
foo(arr8);
foo(arr9);
foo(arr10);
return 0;
}
void foo(int *arr){
int length = 0;
while(arr[length] != '\0'){
length++;
}
printf("Length = %d\n",length);
}
And i got the following Output:
Length = 1
Length = 2
Length = 3
Length = 4
Length = 5
Length = 6
Length = 7
Length = 8
Length = 9
Length = 10
Which prints the Length of all 10 arrays.
Now I'm confused here, because as far of my concern, as I read in some books, there is no way to make it work.
Why foo prints the length of all arrays?
It is illegal to use something like int arr[] = {1,2,3,'\0'}; ?
I know that if the Array has a 0 inside like this int arr[] = {1,2,0,3,4}; the length will be 2, but this is not my question.
This is how C-strings mark their end and length. And as they're just char arrays, naturally you can apply the same to other types of arrays as well.
Just remember that calculating the length of such an array through a pointer has a linear time complexity.
It is illegal to use something like int arr[] = {1,2,3,'\0'}; ?
No. It's perfectly legal. '\0' is an int which is same as 0. It's no different to using any number as marker to identify the end of the array. For example, you can use -1 if you array is going to contain only positive number. So your approach is valid.
The reason you wouldn't usually see in practice it's kind of needless to iterate over an array when you can simply pass it as an extra argument, which is easily understandable from maintenance point of view.
int arr[1024];
size_t len = sizeof arr/sizeof a[0];
func(arr, len);
void func(int *a, size_t length) {
}
Compare this with your approach.
Also, the size is calculated at compile-time whereas in your approach you have iterate over the array. Choosing the right sentinel could become difficult ( o or -1 or whatever) if it's also needed to be an element of the array.
Sidenote: '\0' is really 0 here, as your store ints.
You're using a sentinel. C-style strings have been using this method for decades to mark where the string finishes. It has the same benefits, but it also has the same drawbacks.
As long as you maintain the invariant that the sentinel occours only at the last place of the array you'll be able to get the length of the array. In O(N) time, as you have to traverse the sequence.
Note that you can shrink the sequence by terminating it earlier with a sentinel:
1 2 3 4 0 //
1 2 3 0 * // * as in: anything
But as soon as you do this, you cannot known the size of the array anymore. Even though you could technically append an extra element, a function without knowing the context cannot safely do this. In essence, you know the size of the sequence, but you don't known the size of the array anymore.
If you need a method to use to allow you to carry the array length with the array then try using one of these approaches.
Store the length in the start of the array
So (ideally) array[0], the first element would be a length.
The catch is that that only works if your array has a suitable type and the length fit in that type. You can in principle use union to define an element large enough to hold different types of data, including the length, but it's potentially wasteful.
Maintain a structure to store the array length and a pointer to the array data.
This is something like :
struct arrayinfo_s {
int length ;
char *data ;
};
char name[1000] ;
struct arrayinfo a ;
a.length = sizeof(name) ;
a.data = name ;
myfunc( &arrayinfo ) ;
There are many variations on this possible.
The "standard" convention.
As someone already mentioned, it is typical to track the array length and pass it as a separate parameter to the function.
myfunc( array, length ) ;
If array is a fixed size declared like e.g. int nums[100] ; then you can use sizeof(nums) if the variable was declared in the same function as you used sizeof() or globally.
There is also a variation on this for allowing a function to return an array of unknown length. Typically you would do something like returning a point to the array, but pass a parameter that is a pointer to some integer type to store the length of the new array in.
char *newstuff( int *newlength )
{
char *p = NULL ;
p = malloc( 102 ) ;
if( p == NULL )
{
*length = 102 ;
return p ;
}
else
{
*length = 0 ;
return NULL ;
}
}

Automatic growth in two-dimensional arrays

In the C language, is there a way to automatically grow an array.
For example:
int arr [100] [10];
If the array is full is it possible to have it "automatically" become larger? Or is that only possible if you're using C++. How would you write this in C?
There is no such feature in C: you have to declare the array using pointers, detect the "array is full" condition manually, call malloc, make a copy into an extended array, and free the original one. Even the variable-length arrays would not work, because they let you set their size only once per the array lifetime.
In C++, you can use std::vector<std::vector<int> > instead of a plain array. You still need to detect the "array is full" condition, but the std::vector<T> container takes care of all re-allocations and extensions on resizing for you.
"automatic" growth of any array in C is not possible. If you declare an array statically:
int arr[10];
you have however many memory locations as you indicated. If you want to be able to change it during runtime you need to declare it dynamically using malloc() and make it larger using realloc()
A quick example for you:
int main(void){
int input, count = 0, length = 2;
int * arr = malloc(sizeof(int) * length); // array of size 2
while((input = getchar()) != 'q') //get input from the user
{
getchar(); //get rid of newlines
arr[count] = input;
if(count + 1 == length){ // if our array is running out of space
arr = realloc(arr, length * length); // make it twice as big as it was
length *= length;
}
count++;
}
for(length = 0; length < count; length++) // print the contents
printf("%d\n", arr[length]);
free(arr);
return 0;
}

Dynamic array using ANSI C

I have a char array
char *data[]= {"11", "22", "33", "44", "55"};
How can I add some extra items to it in the end? data[]="66";
I'd like a dynamic array in C.
Thanks
Arrays created using the [] syntax are not dynamic, the length is set at compile-time and cannot change.
UPDATE: Actually, C99 adds so-called "variable-length arrays", which can get their length at run-time. After they've been initialized, however, they can't shrink or expand so the below still applies.
However, an array is trivially expressed when you have pointers: an array can be represented as a pointer to the first element, and a length.
So, you can create a new array by dynamically allocating memory using malloc():
size_t array_length = 3;
int *array = malloc(array_length * sizeof *array);
if(array != NULL)
{
array[0] = 11;
array[1] = 22;
array[2] = 33;
}
You cannot use the {} list of elements here, that's only usable when initializing arrays declared using the [] syntax.
To grow the array, you can use the realloc() function to re-allocate the memory and copy the old values over:
size_t new_length = array_length + 1;
int *bigger_array = realloc(array, new_length * sizeof *bigger_array);
if(bigger_array != NULL)
{
bigger_array[new_length - 1] = 44;
/* We have successfully grown the allocation, remember the new address. */
array = bigger_array;
array_length = new_length;
}
Note that every time you call malloc() (or realloc()), it can return NULL if it failed to allocate the requested block. That's why the if statements are needed. I cut the initial size down a bit from your example to reduce the number of assignment-lines needed, to make the example shorter.
To make the above more efficient, typical dynamical array code uses two length values: one for the actual array (how many values are in the array right now) and one for the memory (how many values to we have room to store). By making the latter value grow in chunks, the total number of memory allocations can be cut down a bit, at the cost of some memory of course.
vc_vector
vc_vector* vector = vc_vector_create(0, sizeof(const char *), NULL);
vc_vector_push_back(vector, "11");
vc_vector_push_back(vector, "22");
vc_vector_push_back(vector, "33");
for (int i = 0; i < vc_vector_count(vector); ++i) {
printf("%s ", (const char*)vc_vector_at(vector, i));
}
// output: 11 22 33
vc_vector_release(vector);
Here is a macro based solution for a dynamic array in C with a very nice syntax to use. Works for any data type.
#include <stdio.h>
#include <stdlib.h>
#include <wondermacros/array/dynamic_array.h>
int main()
{
int* elems = NULL; /* Initialize a dynamic array. */
W_DYNAMIC_ARRAY_PUSH(elems, 1, 2, 3, 4); /* Push some elements. */
/* Iterate all elements. */
W_DYNAMIC_ARRAY_FOR_EACH(int, e, elems) {
printf("%d\n", e);
}
W_DYNAMIC_ARRAY_FREE(elems); /* Free the array only this way since there is a hidden header. */
}
The library uses Boost pre-processor library so Boost library needs to be there at build time.

Resources