C saving strings to 2d array - c

The idea is to read strings from standard input until EOF is reached (in this format "string - string"). Then, break the string into two strings and and save them to a 2d array. The array is dynamically allocated with initially 2 rows and 20 columns, but I would like to add 2 additional rows every time I want to add next strings to it (the function expandmat()). Here's my code:
char ** alloc(int rows, int collums) {
char ** mat;
int i;
mat = malloc(sizeof (char *) * rows);
for (i = 0; i < rows; i++) {
mat[i] = malloc(sizeof (char) * collums);
}
return mat;
}
char ** addtoarray(char ** mat, char * string1, char * string2, int position) {
sscanf(string1, "%s", mat[positon]);
sscanf(string2, "%s", mat[positon+1]);
return mat;
}
char ** getinput(char * longstring, char * string1, char * string2) {
int position = 0, n = 2, max = 30;
char ** mat;
mat = alloc(n, max);
while (fgets(longstring, max, stdin)) {
sscanf(longstring, "%s - %s", string1, string2);
addtoarray(mat, string1, string2, positon);
n += 2;
position += 2;
mat = expandmat(mat, n);
}
return mat;
}
Also, if there is something in this code that doesnt make any sense, could you please tell me how to fix it?
I know this seems like a trivial task but it has been driving me crazy.
Thanks for your help.

Check out the realloc C function to resize mat.
expandmat should realloc mat so that you can add two more rows (it should return the matrix as well, because realloc will copy memory to a new location if necessary)

Wow... The third time that a question like this comes up for today :-).
Please check if my answer here helps you: Array of C structs

Related

how to allocate arrays (in array of pointers) C -- can it be done in one line? with malloc

is there a simple one liner I can use in C to allocate arrays in (pointer of arrays)
This line creates 10 pointers of arrays
char *out[10];
I can't do this
char *out[100]=(char[10][100])malloc(sizeof(char)*10*100);
error: cast specifies array type
same error with
char *out[10]=(char*[10])malloc(sizeof(char)*10*100);
do I need to do it in loop like this
int main()
{
char *out[10];
int x=0;
while(x<10)
{
*(out+x)=malloc(sizeof(char)*100);// is this line correct?
x++;
}
*out[0]='x';
printf("%c\n",out[0][0]);
free(out);
return 0;
}
but this cause warning that
req.c:75:3: warning: attempt to free a non-heap object ‘out’ [-Wfree-nonheap-object]
75 | free(out);
so do I need to allocate and free each array in (array of pointers) in loop
Can't I do allocation and free arrays in array of pointer in one line instead of loop?
or is there anything thing in my loop wrong too
To allocate an array of pointers to strings, you need to do:
char** out = malloc(sizeof(char*[10]));
The whole point of using this form is that each pointer in that array of pointers can be allocated with individual size, as is common with strings. So it doesn't make sense to allocate such with a "one-liner", or you are using the wrong type for the task.
In case you don't need individual sizes but are rather looking for a char [10][100] 2D array with static size, then the correct way to allocate such is:
char (*out)[100] = malloc(sizeof(char[10][100]));
You can allocate the full array in one single step and have pointers inside that array:
char *out[10];
data = malloc(100); //sizeof(char) is 1 by definition
for (int x=0; x<10; x++) {
out[i] = data + x * 10;
}
*out[0] = 'x';
printf("%c\n",out[0][0]);
free(data); // you must free what has been allocated
int i;
char** out = (char**)malloc(sizeof(char*)*10);
for(i = 0; i<10;i++)
out[i] = (char*)malloc(sizeof(char)*100);
out[1][1] = 'a';
OR with same dimensions
#include <stdio.h>
#include <stdlib.h>
void main()
{
int r = 10, c = 100; //Taking number of Rows and Columns
char *ptr, count = 0, i;
ptr = (char*)malloc((r * c) * sizeof(char)); //Dynamically Allocating Memory
for (i = 0; i < r * c; i++)
{
ptr[i] = i + 1; //Giving value to the pointer and simultaneously printing it.
printf("%c ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
free(ptr);
}

How should I make a dynamic array of 1<n<300000

I am trying to solve a problem on a competitive programming page, and it had occurred to me that a good way to solve it would be by making a dynamic array, right now I don't care about the problem and what I want to know is how something like this could be implemented.
The idea is first they give us the number of cases (the size of the array) and then we make certain tours of that array, I would also have to apply it to a matrix of characters (an array of strings), this code that I have here works well when the input of cases is 1 <n <110, but of course, when that range is passed (it should be up to 300000 ) gives me a memory access error Process finished with exit code -1073741819 (0xC0000005), which is normal considering what I'm trying to do, I don't even know if it can, thank you very much in advance!
This is my code:
int main() {
int cases, i, j, max = 0;
while ((scanf("%d", &cases)) != EOF) {
int *victims;
victims = (int *) malloc(cases * sizeof(int));
const char **date;
date = (const char **) malloc(cases * sizeof(char));
for (i = 0; i < cases; i++) {
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
}
for (i = 0; i < cases; i++) {
scanf("%s", date[i]);
scanf("%d", &victims[i]);
}
}
}
The lines
const char **date;
date = (const char **) malloc(cases * sizeof(char));
are wrong. The element is const char*, so you have to allocate for that.
In other words, you have to allocate size of a pointer, not size of a char, for each elements.
Moreover, the objects pointed at by the elements of the array date will be modified via scanf() later, so they should be char*, not const char*.
it should be
char **date;
date = malloc(cases * sizeof(char*));
or
char **date;
date = malloc(cases * sizeof(*date));
Also the line
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
is wrong. You have to allocate one more element for the terminating null-character to allow 10-character strings to be stored there.
It should be:
date[i] = malloc(11 * sizeof(char));//String max length is 10.
Also note that:
You need not multiply sizeof(char) because it is defined to be 1.
Casting the results of malloc() is considered as a bad practice.

difference of *var[n] with (*var)[n]

I have a question regarding the difference between char *<variable>[6] and char (*<variable>)[6].
I was making a code for an exercise which asks to input and store 6 strings and later turn each into an integer. My plan was to make an array of strings to store them and I did char *<variable>[6] = malloc(7*sizeof(char)); but an error showed up saying ' array initializer must be an initializer list ' but when i changed it to char (*<variable>)[6] = malloc(7*sizeof(char)); it can work properly. What is the difference between (*<variable>)[6] and *<variable>[6] ?
My code below:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char (*sixString)m[6] = (char *) malloc(7 * sizeof(char));
int i;
int sum = 0;
for(i = 0; i < 6; i++){
printf("Input for the Number %d: ", i + 1);
scanf("%s", sixString[i]);
//fgets(sixString[i], 100, stdin);
printf("%s\n", sixString[i]);
sum = sum + atoi(sixString[i]);
}
float average = (float)sum/6 ;
printf("Sum is: %d\nAverage is: %.2f\n", sum, average);
free(sixString);
return 0;
}
char *<variable>[6]
is a 6-element array of char*.
char (*<variable>)[6]
is a pointer to 6-element array of char.
Your code allocated insufficient number of bytes. You should use
char (*sixString)[6] = malloc(7 * sizeof(char[6]));
or
char (*sixString)[6] = malloc(7 * sizeof(*sixString));
instead of
char (*sixString)m[6] = (char *) malloc(7 * sizeof(char));
(size is fixed and the extra m is removed)
Note that then you allocate 7 elements of char[6], but you use only 6 of them in the loop.
Allocating extra elements may look inefficient, but cause less harm than allocating insufficient size.

allocating space for pointer to array of pointers

Good day. I have this: MAP_ITEM **map what I think is pointer to array of pointers (correct me if I am wrong please) and I have to allocate space for it. I can allocate space using malloc for 1 pointer, but have no idea how to do this. help would be really appreciated.
Here is an example, written for use with char **, but you can modify for your purposes:
char ** allocMemory(char ** a, int numStrings, int maxStrLen)
{
int i;
a = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
for(i=0;i<numStrings; i++)
{
a[i] = calloc(sizeof(char)*maxStrLen + 1, sizeof(char));
}
return a;
}
call it like this: (for array of 10 strings, each having maximum of 79 characters (leave one for NULL term)
char **arrayOfString;
arrayOfString = allocMemory(arrayOfString, 10, 80);
//
You also need to free memory created with allocMemory
void freeMemory(char ** a, int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
if(a[i]) free(a[i]);
free(a);
}
Call it like this:
freeMemory(arrayOfStrings, 10);
Import the stdlib.h
Then use the malloc function.
Where is an example for a one dimentional array:
int* my_in_array = (int*) malloc(sizeof(int) * size_of_my_array);
Note that malloc receives the number of bytes you want to allocate, so sizeof will tell you how many bytes a datatype will need (in this case an int, but it can be used for chars, structures, ...) and then I multiplicate it by size_of_my_array, wich is the number of elements of my array.
Now, just try to se this for you case.

Initialising 2d dynamic Array

I am new to C and trying to initialise a 2D array. I need both columns of the array to be char *, as they will contain string values.
I have it working with the array storing ints but for some reason, when I try to store string values when it prints it displays (null). Below is the code for how I am initialising and storing the data as an int (This appears to be working).
int **array;
int row = 0;
array = malloc(2 * sizeof(int*));
int i;
for (i = 0; i < 2; i++)
{
array[i] = malloc(2 * sizeof(int));
}
array[0][0] = i;
array[0][1] = i;
printf("array[0][0]: %i\n", array[0][0]);
Below is how I am doing the above but using string values instead.
char **array;
int row = 0;
array = malloc(2 * sizeof(char*));
int i;
for (i = 0; i < 2; i++)
{
array[i] = malloc(2 * sizeof(char*));
}
array[0][0] = "Test[0][0]";
array[0][1] = "Test[0][1]";
printf("array[0][0]: %s\n", array[0][0]);
Thanks for any help you can provide.
You have the wrong level of pointer indirection, which is over-complicating things.
I think it would be easier for you if you thought of the array as an array of structures, each structure holding two pointers:
struct row {
char *column1;
char *column2;
};
then it's (hopefully) clearer that once you've allocated an array of struct row, you have two pointers in each row, you don't need to allocate room for the pointers themselves.
const size_t num_rows = 1;
struct row * rows = malloc(num_rows * sizeof *rows);
if(rows != NULL)
{
rows[0].column1 = "row 0, column 1";
rows[0].column2 = "row 1, column 2";
}
Note that this uses string literals, otherwise you might need to allocate room for the strings to be stored, depending on where the data comes from.
The num_rows value could of course come from anywhere in your program, I'm just trying to illustrate what controls the number of rows memory is allocated for.
Save yourself the trouble and don't use 2D arrays in C. It's more convenient to use 1D arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
const int nstrings = 2;
const int width = 20; //width of maximum string.
char* array = (char*)malloc(sizeof(char)*nstrings*width);
strcpy(&array[0*width],"Test[0][0]");
strcpy(&array[1*width],"Test[1][0]");
printf("string 0: %s\n", &array[0*width]);
printf("string 1: %s\n", &array[1*width]);
free(array);
}

Resources