1

I have to store some strings given in the args of a c code. I iterate over them but I can't store them properly because I don't know the length of those and neither their number. The better method should be a 2d array of pointers, so I can dynamically allocate memory for every new string. The problem is that I'm new on c and I have a lot of confusion about that technique. I tried to initialize a double pointer and use a function to insert elements, it allocates space for another column(new string) and set the length(size of string).

char** files;
int files_i=0;
void insert(char** root,char[] str)
{
 root=(char **)malloc(sizeof(char *));
 root[files_i]=(char *)malloc(sizeof(char)*sizeof(str));
 root[files_i*sizeof(str)]=str;
 i++;
} 

I pass to the function the double pointer and the string I need to "append". It's not working and I have also really big doubts on how to iterate over that...

Mahendra Gunawardena
1,9745 gold badges26 silver badges45 bronze badges
asked May 21, 2020 at 18:47
0

2 Answers 2

2

What you need is the following

char **files = NULL;
size_t files_i = 0;
//...
int insert( char ***root, const char str[], size_t i )
{
 char *p = malloc( strlen( str ) + 1 );
 int success = p != NULL;
 if ( success )
 {
 char **tmp = realloc( *root, ( i + 1 ) * sizeof( char * ) );
 if ( success )
 {
 strcpy( p, str );
 tmp[i] = p;
 *root = tmp;
 }
 else
 {
 free( p );
 }
 }
 return success;
}

and then in the caller you can write for example

if ( insert( &files, some_string, files_i ) ) ++files_i;

Here is a demonstrative program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int insert( char ***root, const char str[], size_t i )
{
 char *p = malloc( strlen( str ) + 1 );
 int success = p != NULL;
 if ( success )
 {
 char **tmp = realloc( *root, ( i + 1 ) * sizeof( char * ) );
 if ( success )
 {
 strcpy( p, str );
 tmp[i] = p;
 *root = tmp;
 }
 else
 {
 free( p );
 }
 }
 return success;
}
int main(void) 
{
 char **files = NULL;
 size_t files_i = 0;
 if ( insert( &files, "Hello", files_i ) ) ++files_i; 
 if ( insert( &files, "World", files_i ) ) ++files_i; 
 for ( size_t i = 0; i < files_i; i++ )
 {
 puts( files[i] );
 }
 for ( size_t i = 0; i < files_i; i++ )
 {
 free( files[i] );
 }
 free( files );
 return 0;
}

Its output is

Hello
World
answered May 21, 2020 at 19:23
Sign up to request clarification or add additional context in comments.

Comments

2
  1. use strlen(str) instead of sizeof(str) for calculating the string length.
root[files_i]= malloc(strlen(str) + 1); // +1 for null character at the end of the string
if(!root[file_i]) {return;}
  1. if you want to copy string, use strcpy instead of using = operator. Or use strdup (if you use strdup, you do not need to allocate memory for character pointer).
strcpy(root[files_i],str); // copy string str to "file_i" position of array root
  1. if you use the global counter file_i, you should use realloc for root, because the size of root has to be vary (i think it's typo, the i++ should change to file_i++ ?).
root= realloc(root, sizeof(char *) * (file_i + 1));
// do not forget to check the return value of malloc or realloc function.
if(!root) {return;}
  1. Do not cast malloc or realloc function. See at Do I cast the result of malloc?
answered May 21, 2020 at 19:04

1 Comment

You were right and clear on everything, i really appreciate your help and i understood a lot of this topic. Thank you very much!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.