I'm trying to make a 2D array in C with malloc for "hash map" project but as usual. something happend !
basically I have an issue of accessing the 3rd element of the 1st array arr[0][3], it's super weird (at least to me) ,so let me show you the code
1- create 2D array:
int main(void){
char*** table;
table = malloc(sizeof(char*) * 10);
//create array inside table
table[0] = malloc(sizeof(char) * 20);
return 0;
}
2- assign some strings to 1st array table[0]:
table[0][1] = "test1";
table[0][2] = "test2";
table[0][3] = "test3";
table[0][4] = "test4";
...
table[0][n] = "testn";
3- now the magic happens:
// 10 => n >= 0;
printf("%s", table[0][n]);
returns -> malloc(): corrupted top size Aborted (core dumped)
in that moment I tried everything a noob would do , so somehow I figured out that the 3rd string test3 is the problem.
so if I remove the table[0][3] line, all works great !!
table[0][1] = "test1";
table[0][2] = "test2";
//table[0][3] = "test3";
table[0][4] = "test4";
...
table[0][n] = "testn";
// 10 => n >= 0;
printf("%s", table[0][n]);
returns => "testn";
EDIT
for Vlad From Moscow
that works:
for(int i=0; i<10; i++{
table[0][n] = "test";
//here works
printf("%s", table[0][n];
}
//here also works fine
printf("%s", table[0][3];
You declared the pointer table like
char*** table;
So the expression table[0] used in this statement
table[0] = malloc(sizeof(char) * 20);
has the type char ** and you allocated memory for 20 characters.
If sizeof( char * ) is equal to 8 then the allocated memory can accommodate only two pointers of the type char *. If sizeof( char * ) is equal to 4 then the allocated memory can accommodate only 5 pointers of the type char *.
You need to do something like the following
char*** table;
table = malloc(sizeof(char**) * 10);
//create array inside table
for ( size_t i = 0; i < 10; i++ )
{
table[i] = malloc(sizeof(char *) * 20);
}
These memory allocations will simulate a two dimensional array of the type char * table[10][20].
On the other hand, you could at once allocate memory for a two-dimensional array like
char * ( *table )[20] = malloc( sizeof( char *[10][20] ) );
Related
beginner here
This is absolutely infuriating me, how do I create an array that holds strings where the length / amount of strings are unknown? I essentially want to create a dictionary where
array[0] = "word"
array[1] = "word2"
array[2] = "word3"
and so on
I tried :
array** = malloc(INIT); where init was defined as 10
memset(array, '\0', 10)
then, under a loop
array[i] = malloc(INIT)
array[i] = string from another source ( array2[i] ) (array2 is a char*)
but that just gives errors / junk text and I have no clue how to assign strings to the array
I'm having a hard time understanding pointers / jargon in general, I've looked at all the similar questions and can't understand any of the answers.
Try doing this -
int main(){
int i;
char *arr[10];
for(i=0;i<10;i++){
char str[1000];
scanf("%s", str);
arr[0] = (char*) malloc(strlen(str));
strcpy(arr[0], str);
}
return 0;
}
You can dynamically create an array of pointers to strings and in that way keep it flexible:
char** array = malloc(sizeof(char*)*n); // allocates an array of char* pointers
if you later need to extend the array use realloc
char** newarray = realloc(array,sizeof(char*)*(n+1));
if (newarray != NULL)
{
array = newarray;
...
}
You must also remember to allocate space for where the pointers point to for storing your strings
array[i] = strdup("blabla");
or
array[i] = malloc(strlen("blabla")+1);
strcpy(array[i], "blabla" );
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);
}
void dynamicArray(int** num1, int** num2, char*** str, int size)
{
int i = 0;
*(num1) = (int*)malloc(sizeof(int) * size);
*(num2) = (int*)malloc(sizeof(int) * size);
*(str) = (char**)malloc(sizeof(char*) * size);
for( i = 0; i < size; i++){
*(*(str) + i) = (char*)malloc(sizeof(char) *5);
}
return;
}
Did I successfully allocate memory correctly for my ***char in particular? I'm trying to create a 2-D array of "sentences". I'm having an issue in my main program and I think this may be the problem.
From the comments:
The issue I'm having is with the string array. In another function, I assign each *strPtr a string. When I do so, it overwrites all the values before it. i.e. *strPtr = "You" *strPtr + 1 = hi. NOW *strPtr + 0 well equal hi.
Since this code looks fine, but you're explanation here looks funny, I think you're using the arrays wrong.
*strPtr[1] != *strPtr + 1
*strPtr[1] == *(strPtr + 1) == strPtr[1][0]
You should be using one of the forms from the second line, not the first.
I have char * lines[1000] string that can hold 1000 characters. How to create 100 arrays of that string. I get error with this code down.
char * lines[1000];
lines = (lines*)malloc(100 * sizeof(lines));
main.c:19:20: error: expected expression before ')' token
The simplest way is:
char lines[100][1000];
Alternatively:
char* lines[100];
int i;
for (i = 0; i < 100; i++) {
lines[i] = malloc(1000);
}
...
for (i = 0; i < 100; i++) {
free(lines[i]);
}
The latter is a bit more flexible in that -- with minor modifications -- it permits you to allocate a different amount of memory for every string.
It looks like you want an array strings, each string holding at most 1000 characters. There are some issues with your code.
You've declared an array of char *s but what you really want is a pointer to an array of chars. For that, your declaration should be
char (*lines)[1000];
On the other hand, you shouldn't forget about the NULL bytes at the end of strings, and should probably instead declare
char (*lines)[1001];
To set the pointer, you'll want to use
lines = (char (*)[1001]) malloc(100 * sizeof(char[1001]));
or
lines = (char (*)[1001]) malloc(100 * sizeof(*lines));
the latter working because, with lines a pointer to an array of chars, *lines is a char[1001]. Remember to make sure you didn't get a NULL pointer back.
At the end, you should free the memory you've malloced with
free(lines);
You can write a for-loop as:
char * lines[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
lines[i] = (char*)malloc(100 * sizeof(lines));
}
Don't forget to free-up the memory pointed by all the pointers
for (i = 0; i < 1000; i++)
{
free(lines[i])
}
Why don't you create a 2 dimensional array?
I am trying to allocate a array of char*'s in C.
I know the number of columns in advance, but not the rows
and I want to allocate the rows as and when needed.
I tried to use:
char *(*data)[NUMCOLS]; //declare data as pointer to array NUMCOLS of pointer to char
data = malloc(sizeof(char*));
now, the above line should allocate for data[0] ... correct?
then, I must be able to use the row like
data[0][1] = strdup("test");
.
..
data[0][NUMCOLS-1] = strdup("temp");
I am getting seg fault. I am not able to understand what is wrong here.
can anyone please help.
You haven't allocated enough memory for the things that you want to store. In this particular case, that would be:
data=malloc(sizeof(char*)*NUMCOLS*NUMROWS);
To resize the array, you would use:
data=realloc(data,(size_t)sizeof(char*)*NUMCOLS*NEW_NUMROWS);
More about it (reallocation) here
I would do this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
char ***a = NULL;
a = realloc( a, 1 * sizeof(char **) ); // resizing the array to contains one raw
a[0] = malloc( 3 * sizeof(char *) ); // the new raw will contains 3 element
a[0][0] = strdup("a[0][0]");
a[0][1] = strdup("a[0][1]");
a[0][2] = strdup("a[0][2]");
a = realloc( a, 2 * sizeof(char **) ); // resizing the array to contains two raw
a[1] = malloc( 3 * sizeof(char *) ); // the new raw will contains 3 element
a[1][0] = strdup("a[1][0]");
a[1][1] = strdup("a[1][1]");
a[1][2] = strdup("a[1][2]");
for( int rows=0; rows<2; rows++ ){
for( int cols=0; cols<3; cols++ ){
printf( "a[%i][%i]: '%s'\n", rows, cols, a[rows][cols] );
}
}
}