1

I want to create an array of strings called arguments that copies entries from an array of strings called words (from words[1] until the end). I'm having trouble with malloc and don't really understand how much I should malloc. I first sum all the characters in total that I'm going to be storing. The last entry in words is always NULL.

words = ["jargon","hello", "world", NULL];
int sum = 0;
for(int i = 1; words[i] != NULL; i++) {
    sum += strlen(words[i]);
}

So i will have sum characters in my array called arguments. So now i malloc and copy the required entries.

char **arguments = malloc(sum * sizeof(char));
for(int i = 0; words[i] != NULL; i++) {
    strcpy(arguments[i], words[i+1]);
}

However, i get a memory buffer overflow. If i change it to

char **arguments = malloc(sum * sizeof(*arguments));

I get past the memory buffer overflow but instead am greeted with an uninitialized value in arguments[i] in the next line. Could anyone shed some light on what's going on?

Edit: Sorry about the poor style and thanks for the advice.

11
  • 1
    What is words? Please provide a minimal reproducible example Commented Nov 20, 2019 at 9:29
  • ... and most likely malloc(sum * sizeof(char)) -> malloc(sum * sizeof(char*)) Commented Nov 20, 2019 at 9:30
  • 2
    for(int i = 1; <-- first index of an array is 0 Commented Nov 20, 2019 at 9:30
  • 1
    @Jabberwocky: There is no evidence that the choice to take data starting from words[1] is a choice of style rather than function. As stated in the question, it is a functional requirement. Specifically, they are given a pointer, and the required task is to copy from words[1] on. This arises naturally when the standard argv of main is passed to a routine and one desires to copy the arguments but not the program name. Commented Nov 20, 2019 at 10:25
  • 1
    @EricPostpischil That's more or less what's going on but I couldn't find a way to articulate it nicely. Thank you for finding the words for me Commented Nov 20, 2019 at 10:29

1 Answer 1

1

I want to create an array of strings called arguments that copies entries from an array of strings called words

If so then this loop does not make sense.

int sum = 0;
for(int i = 1; words[i] != NULL; i++) {
    sum += strlen(words[i]);
}

Moreover indices in C start from 0. It is unclear why the index i in you loop starts from 1.

You need to allocate an array of pointers and then allocate memory for strings that will be pointed to by elements of the array of pointers.

What you need is the following

size_t n = 0;

while ( words[n] != NULL ) ++n;

char **arguments = malloc( n * sizeof( *arguments ) );

for ( size_t i = 0; i != n; i++ )
{
    size_t length = strlen( words[i] );
    arguments[i] = malloc( length + 1 );
    strcpy( arguments[i], words[i] );
}

If you want to exclude the string words[0] from the set of copied strings then the code snippet can look like

size_t n = 0;

while ( words[n+1] != NULL ) ++n;

char **arguments = malloc( n * sizeof( *arguments ) );

for ( size_t i = 0; i != n; i++ )
{
    size_t length = strlen( words[i+1] );
    arguments[i] = malloc( length + 1 );
    strcpy( arguments[i], words[i+1] );
}
Sign up to request clarification or add additional context in comments.

5 Comments

Please do not just post code for an answer without explaining it. Say why allocating space for the total number of characters and assigning it to a pointer to pointer to char is wrong. Say why space has to be allocated for pointers instead. Say why space has to be allocated for each string. Say why one has to be added to each. Additionally, we should not model code that ignores the possibility that malloc returns null. Students should be taught good error handling and robust programming practices as soon as feasible.
@EricPostpischil Why not open teaching class here? Please don't take me for wrong, I'm making a fair point here.
Starting with words[1] appears deliberate, as it is both stated explicitly in the text and manifested in the code, including copying from words[i] to arguments[i-1]. The latter shows the OP is aware of zero-based indexing and supports the hypothesis that starting with words[1] is deliberate. Therefore, suggesting the OP was wrong in this is likely a mistake. Starting the answer with it instead of starting with the key problem in the code is a detraction.
@EricPostpischil Please post your elaborative post with minor details starting from binary. Happy to upvote.
The correct solution is given despite the unnecessary comment about the indexing, so upvoted.

Your Answer

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.