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.
Related
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);
}
I'm a noob so don't be hard on be.
Instead of something like this;
char string[NUM OF STRINGS][NUM OF LETTERS];
Is it possible to dynamically allocate how many strings will be in the array with malloc just like when you dynamically allocate memory for char pointer? Something like this:
int lines;
scanf("%d", &lines);
char *string[NUM OF LETTERS]
string = malloc(sizeof(char) * lines);
I tried it but it doesn't work; There must be something I'm doing wrong.
The other solution I thought of was:
int lines;
scanf("%d", &lines);
char string[lines][NUM OF LETTERS];
but I want to know if that's possible using malloc.
You can also use malloc for each word, like this
char **array;
int lines;
int i;
while (scanf("%d", &lines) != 1);
array = malloc(lines * sizeof(char *));
if (array != NULL)
{
for (i = 0 ; i < lines ; ++i)
{
int numberOfLetters;
while (scanf("%d", &numberOfLetters) != 1);
array[i] = malloc(numberOfLetters);
}
}
where numberOfStrings and lengthOfStrings[i] are integers that represent the number of strings you want the array to contain, an the length of the ith string in the array respectively.
You have two methods to implement this.
First is more complicated, cause it requires the allocation of memory for array of pointers to strings, and also allocation of memory for each string.
You can allocate the memory for entire array:
char (*array)[NUM_OF_LETTERS]; // Pointer to char's array with size NUM_OF_LETTERS
scanf("%d", &lines);
array = malloc(lines * NUM_OF_LETTERS);
. . .
array[0] = "First string\n";
array[1] = "Second string\n";
// And so on;
A disadvantage of the second method is that NUM_OF_LETTERS bytes are allocated for each string. So if you has many short strings, the first method would be better for you.
In case you want contiguous memory allocation:
char **string = malloc(nlines * sizeof(char *));
string[0] = malloc(nlines * nletters);
for(i = 1; i < nlines; i++)
string[i] = string[0] + i * nletters;
For more detailed explanation: Read FAQ list · Question 6.16.
int lines;
scanf("%d", &lines);
char (*string)[NUM OF LETTERS]
string = malloc(sizeof(*string) * lines);
char **ptop;
int iStud;
int i;
printf("Enter No. of Students: ");
scanf("%d",&iStud);
ptop=(char **) malloc(sizeof(char)*iStud);
flushall();
for(i=0;i<iStud;i++)
{
ptop[i]=(char *) malloc(sizeof(char)*50);
gets(ptop[i]);
}
for(i=0;i<iStud;i++)
{
puts(ptop[i]);
}
free(ptop);
This question already has answers here:
How to read string from keyboard using C?
(6 answers)
Closed 8 years ago.
I wanna write a program with an array of pointers to char where I store strings read from the console in it. A string is determined by \n. Any ideas how I can do this?
Code with mix of pseudocode so far:
char** arr;
arr = malloc(sizeof(char*) * 5);
arr = malloc(sizeof(char) * 10);
while (No \n read) {
// Store the string in the array
}
I really have no clue how to do this.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
char **arr;
arr = malloc(sizeof(char*) * 5);//for 5 string
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);//reserved storage space length 9
scanf("%9[^\n]%*c", arr[i]);//Read until \n, and discard \n
}
printf("\n");
//check print and free
for(i=0;i<5;++i){
puts(arr[i]);
free(arr[i]);
}
free(arr);
return 0;
}
int i, n;
char **arr;
arr = malloc(sizeof(char*) * 5);
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);
}
i=0;
while(i<5 && 1==scanf("%9[^\n]%*c", arr[i]))
++i;
n = i;
printf("\n");
//check print
for(i=0;i<n;++i){
puts(arr[i]);
}
//deallocate
for(i=0;i<5;++i)
free(arr[i]);
free(arr);
You can use this one.
Creating the new char variable and allocate the memory for that. Then get the input like this.
p=(char *)malloc(100);
while ( (*p=getchar())!='\n')p++;
*arr[0]=p;
If you want to create the multiple lines then allocate the memory for that char variable dynamically then store that in the array of pointers.
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);
}
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