*items[aux_rows] = name;
is wrong on two counts.
Both *
and []
dereference their unary operand. If items
is a char **
, items[n]
is a char *
, and *items[n]
is a char
.
This attempts to assign an array to the first element of each buffer.
Secondly, arrays cannot be copied by assignment. Use strcpy
to copy strings from one buffer to another.
That said, you could simply read your strings directly into the pre-allocated buffers, and do away with the temporary buffer.
In this line,
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
columns
should be items
.
Some things of note:
sizeof (char)
is guaranteed to be 1
. Its use is superfluous.
The return of malloc
should not be cast in C.
malloc
can fail. scanf
can fail. You should get in the habit of not ignoring return values.
scanf("%s", ...)
is as dangerous as gets
. At a minimum, use field-width specifiers to limit input (should be the size of your buffer minus one).
char foo[128];
if (1 != scanf("%127s", foo))
/* handle error */;
Note that using the %s
limits input to not contain any whitespace. scanf
in general is a terrible tool, consider a line based approach using fgets
.
With that said, the minimum changes to make this reasonably safe:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31
void die(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
size_t rows;
printf("Number of items: ");
if (1 != scanf("%zu", &rows))
die("Failed to read input.");
char **items = malloc(sizeof *items * rows);
if (!items)
die("Failed to allocate memory.");
for (size_t i = 0; i < rows; i++) {
if (!(items[i] = malloc(MAX)))
die("Failed to allocate row.");
printf("Name of item %zu: ", i + 1);
if (1 != scanf("%30s", items[i]))
die("Failed to read item input.");
}
for (size_t i = 0; i < rows; i++) {
puts(items[i]);
free(items[i]);
}
}