Dynamically Size Array in C - c

So If I have something that was Dynamic (IE iterated through a for loop) similar to this...
for (i=0; i <= SCREENWIDTH; i++)
{
}
And I wanted to create an array of size SCREENWIDTH and add entries to it. Is there a way I can do this?
so PSUEDO wise it would be...
int[SCREENWIDTH] e = {1,2,....SCREENWIDTH}
for (i=0; i <= SCREENWIDTH; i++)
{
e[i]= i;
}

You can do this like so:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int SCREENWIDTH = 80 ;
int *arr = (int *)malloc( sizeof(int) * SCREENWIDTH ) ;
if( NULL != arr )
{
for( int i = 0; i < SCREENWIDTH; ++i )
{
arr[i] = i ;
}
for( int i = 0; i < SCREENWIDTH; ++i )
{
printf( "%d, ", arr[i]) ;
}
printf("\n") ;
}
}

In C you can create dynamic array using malloc. Example in your case:
int * e = (int*)malloc(SCREENWIDTH*sizeof(int));
Once you allocate memory dynamically in this way. The next think you can do is initialization of the array using the loop.
There is a mistake the way you are accessing the loop. In C The indexing starts from 0 to n-1.
Example: In your case you can access only from e[0] to e[SCREENWIDTH-1].
So, please correct your loop by making it i < SCREENWIDTH. So, it will be
int *e = (int*)malloc(SCREENWIDTH*sizeof(int));
for (i=0; i < SCREENWIDTH; i++)
{
e[i]= i;
}

Related

How to compare jagged array to another array in C?

I've been trying to use a jagged array for a project of mine, meanwhile this is just a test furthermore I'll use it in my project. The question is the following How could I compare each element from each array, so in the code below I have three arrays, after them, I have one more which will be used to compare to the first ones,here what I have so far.
#include <stdio.h>
#include <stdlib.h>
int main(){
int row0[4] = {0,1,3,0};
int row1[4] = {5,6,9,10};
int row2[4] = {9,0,1,10};
int aux[4] = {9,6,9,10};
int *result[3] = {row0,row1,row2};
int size[3] = {4,4,4}, k =0;
for (int i = 0; i < 3; i++) {
int *ptr = result[i];
for (int j = 0; j < size[k]; j++) {
if(ptr[j] == aux[j])
{
printf("%d\n",ptr[j]);
}
ptr++;
}
printf("\n");
k++;
result[i]++;
}
return 0;
}
The result of it is 5, but I'd like to loop over all the values from the array that starts with 5, to find out if the all the other values are equal, in other words I want to know which array is equal to the "aux" array.
You have the (inner) loop:
int *ptr = result[i];
for (int j = 0; j < size[k]; j++)
{
if(ptr[j] == aux[j])
{
printf("%d\n",ptr[j]);
}
ptr++;
}
Since you increment both j and ptr, you're doing far too much incrementing. It's probably best to remove the ptr++; line.

C - create 3D array of ints and initialize it to zeros

I'm trying to create a 3D array of ints initialized to zeros each of fixed size denoted as "dim".
For example, for dim=3, it will have 27 cells for ints.
I tried this:
int ***board;
int **rows;
int *tried;
board = calloc(dim,sizeof(int**));
rows = calloc(dim*dim, sizeof(int*));
tried = calloc(dim*dim*dim, sizeof(int));
int i;
int j;
int k;
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
for (j=0 ; j<dim ; j++) {
board[i][j] = tried + j*dim + i*dim*dim;
}
}
for (i=0 ; i<dim ; i++) {
for (j=0 ; j<dim ; j++) {
for (k=0 ; k<dim ; k++) {
board[i][j][k] = 0;
}
}
}
Trying to debug it, I found that it works until:
board[1][1][0] = 0
And then the program gets stuck and i just can't find the reason.
Can someone explain this please?
Thanks!
First about the error in your code. Compare this:
rows = calloc(dim*dim, sizeof(int*));
to this:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
The entire size of the array allocated to rows is dim*dim elements. So, already in the second iteration of this loop, you access it out of bounds. You probably meant:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim;
As I already mentioned in the comment, this is not a 3D array. It mimics the usage in code by using pointers and you're using a kind-of clever trick here, so you only need 3 allocations in total. This might be a good idea under the following conditions:
your dim is variable at runtime, so you can't know it in advance, and
you have to write code for compilers that don't support VLAs1) (variable-length-arrays).
If one of this conditions is not true, it's much better to use a real 3D array. If the array doesn't have to live after leaving your function and the size isn't huge, just use a simple variable with automatic storage duration like
int board[3][3][3] = { 0 }; // possibly #define the dimension
or, for a variable dim, requiring a compiler supporting VLAs
int board[dim][dim][dim] = { 0 };
If on the other hand, the array will be huge and/or you need to return it from your function, you indeed have to allocate it dynamically. Then just use the following:
int (*board)[3][3] = calloc(3, sizeof *board); // static size
int (*board)[dim][dim] = calloc(dim, sizeof *board); // dynamic case, with VLA suppport
Also note that calloc() already sets your allocated memory to 0, so no need for looping all over it.
Side notes:
with sizeof, prefer the expression form, so instead of writing
int *a = calloc(5, sizeof(int));
better write
int *a = calloc(5, sizeof *a);
this avoids errors when you later change the type of a.
always check the return value of malloc() and friends -- they might return a null pointer (e.g. when you're running out of memory).
1) VLAs don't exist in the oldest standards C89/C90 -- they were introduced in C99 as a mandatory feature, but later made optional in C11. This allows C11 compilers to omit them, which might make sense when e.g. targeting embedded systems. In practice, you can safely assume a C11 compliant compiler supports them if it isn't special purpose.
I rewrote your code to show how allocation of a 3D array could look like. And as pointed out in the comments, there's no need to initialize the array to 0 since calloc does that for you. Had you used malloc the array would not have been initialized.
#include <stdlib.h>
#include <stdio.h>
#define dim (3u)
int main() {
int x;
int y;
int z;
int ***cube;
cube = calloc(dim, sizeof(int**));
for (z = 0; z < dim; z++) {
cube[z] = calloc(dim, sizeof(int*));
for (y = 0; y < dim; y++) {
cube[z][y] = calloc(dim, sizeof(int));
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
cube[z][y][x] = z + y + x;
}
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
printf("%d ", cube[z][y][x]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
What you want to store in it is up to you, in my example I wrote the sum of the counter to each index.
Code below is Unlicense.
I will suggest something different. Just create a 1D array and set some boundaries to interpret it as 3D. I added some test cases for you to better visualize how it works. Do not forget to look at how easy 'calloc' call is. Here is the code:
#include <stdlib.h>
#include <stdio.h>
int getindex(int dim, int x, int y, int z) {
return z * dim * dim + y * dim + x;
}
void printarray(int* tdarray, int dim) {
printf("[\n");
for (int i = 0; i < dim; i++) {
printf("\t[\n");
for (int j = 0; j < dim; j++) {
printf("\t\t[");
for (int k = 0; k < dim; k++) {
if (k == 0) printf("%d", *(tdarray + getindex(dim, k, j, i)));
else printf(",\t %d", *(tdarray + getindex(dim, k, j, i)));
}
printf("]\n");
}
printf("\n\t]\n");
}
printf("]\n");
}
int main() {
int dim = 10;
size_t arraysize = sizeof (int) * dim * dim * dim;
int lookupindex = getindex(dim, 7, 5, 4); /* Numbers picked randomly */
int* tdarray = (int*) malloc(arraysize);
calloc(*tdarray, arraysize);
/* Below is test code and visualizations, all magic happens above.*/
if (*(tdarray + lookupindex) == 0) *(tdarray + lookupindex) = 7;
printf("tdarray[x:%d, y:%d, z:%d]:\t%d\n\n", 7, 5, 4, *(tdarray + lookupindex));
printarray(tdarray, dim);
printf("\n\n\n\n\n\n\n\n\n\n");
for (int i = 0; i < getindex(dim, 9, 9, 9) + 1; i++) *(tdarray + i) = i;
printarray(tdarray, dim);
free(tdarray);
}

How to use a for loop index outside of for loop in C (selection sort)

I am trying to do a selection sort where I am going through a list of integers, picking out the smallest number, and swapping it with a bigger number earlier in the list. This code is just practicing with a short string of 4 integers. What I am struggling with is getting through the whole list of integers to find the smallest number before moving on. I found that this works great as its own nested for loop, but then I can't 'remember' at which index that smallest number was at when trying to swap integers (this would be the line of code that is commented out, as it will not know what 'j' is). If I attempt doing this within the for loop then I prematurely swap the first integer that is smaller than the one I am swapping with before seeing if there are any other smaller integers. Any tips in the right direction would be much appreciated. Thank you!
int main (void)
{
int tmp;
int n = 4;
int values[] = {5,3,4,1};
for (int i=0; i < n; i++)
{
int minimum = values[i];
for (int j=1; j < n; j++)
{
if (values[j]<minimum)
{
minimum=values[j];
}
}
tmp = values[i];
values[i] = minimum;
//values[j] = tmp;
}
}
You need to add a variable minimumIndex which is the index of the minimum value. Set it to j when you update the value of minimum, and it will give you the index of the minimum at the end of the loop. Make also to initialize it with a correct value: Since mimimum is initialized to values[i], minimumIndex should be initialized to i.
Note also that you have a bug: You start the inner loop at j=1, but it should start with i or i+1 so that you skip over the elements which have already been placed.
Just keep the index of the element with the minimal value. For example
#include <stdio.h>
int main ( void )
{
int values[] = { 5, 3, 4, 1 };
size_t n = sizeof( values ) / sizeof( *values );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", values[i] );
}
putchar( '\n' );
for ( size_t i = 0; i < n; i++ )
{
size_t minimum = i;
for ( size_t j = i + 1; j < n; j++ )
{
if ( values[j] < values[minimum] )
{
minimum = j;
}
}
if ( minimum != i )
{
int tmp = values[i];
values[i] = values[minimum];
values[minimum] = tmp;
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", values[i] );
}
putchar( '\n' );
}
Pay attention to that the index of the inner loop should start with the value i + 1.
for ( size_t j = i + 1; j < n; j++ )
^^^^^

How to make strings stick together while radix sorting?

I have to make a program that sort strings (with exact length 7 chars) by using radix sort. I already made a function that sort each column separately. My problem is how to make the whole string move, not just one char. It's really problematic for me to see how should it work in C.
I made one array "char strings[3][8]" and "char output[3][8]" to get sorted 3 strings with exact 7 chars in each one. For example sorting these strings:
strcpy(strings[0], "kupbars");
strcpy(strings[1], "daparba");
strcpy(strings[2], "jykaxaw");
In output I get:
dakaaaa
juparbs
kypbxrw
Each column is sorted correctly but chars don't stick together. I tried many ways for 3 hours but nothing works.
My code looks like this:
void countingSort(char a[][8], char b[][8]) {
int c[123];
for (int pos = 6; pos >= 0; pos--) {
for (int i = 0; i < 123; i++)
c[i] = 0;
for (int i = 0; i < 3; i++)
c[(int)a[i][pos]]++;
for (int i = 1; i < 123; i++)
c[i] += c[i - 1];
for (int i = 2; i >= 0; i--) {
b[--c[(int)a[i][pos]]][pos] = a[i][pos];
}
}
}
(There are constants limiting string length etc. because it's easy to change it to variable - I just focused on getting this program work properly.)
Try changing the loop to move an entire string:
for (int i = 2; i >= 0; i--) {
int k = --c[(int)a[i][pos]];
for(int j = 0; j < 8; j++) {
b[k][j] = a[i][j];
}
}
You could do a circular list but it's a little overhead. I propose you to use memmove().
#include <string.h>
void array_move_forward(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][6];
memmove(array[i] + 1, array[i], 6);
array[i][0] = tmp;
}
}
void array_move_rewind(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][0];
memmove(array[i], array[i] + 1, 6);
array[i][6] = tmp;
}
}
A other solution would be to manipulate your string yourself and using a index, that indicate the first letter of your string.
{
char str[7];
int i = 0;
...
int j = i;
for (int k = 0; k < 7; k++) {
char tmp = str[j++ % 7];
}
}
With that you could rotate your string just with i++ or i--.
struct my_string_radix {
char str[7];
int begin;
}

Removing duplicate entry from an array using hashmap

int main(array<System::String ^> ^args)
{
int arr[]={1,2,3,2,9,8,1,2,3,9};
int a[9];
int size = sizeof(arr)/sizeof(arr[0]);
int str[256]= {'\0'};
int i = 0;
for(i ; i < size ; i++)
{
if(str[arr[i]] == 0 )
str[arr[i]]= 1;
}
for( i = 0 ; i < size ; i++)
{
if( str[arr[i]] == 1)
{
a[i] = arr[i];
}
}
for(i=0 ; i < size ; i++)
{
printf("%d->",a[i]);
}
return 0;
}
still in the new array a,I am getting old data...not sure wats missing here...
Any help would be highly appreciated.
Thanks in advance.
Logical mistakes
the final array won't go till size
the indexing for a is wrong
Simply use one loop to achieve this, analyze following :
int i = 0,j=0;
for( ; i < size ; i++)
{
if(str[arr[i]] == 0 )
{
str[arr[i]]= 1;
a[j++] = arr[i];
}
}
Now iterate till j on final array a

Resources