0

I am trying to create a simple array-expanding function, which creates a new array with the same values as the previous array expanded by a value:

char* test(char array[], int expandBy) {
    char newArray[sizeof(array) + expandBy];
    strncpy(newArray, array, sizeof(array));

    return newArray;
}

However, I am getting the compile-time error expression must have a constant value. All of the answers that I have seen to similar questions suggest using a macro, but I can't use a macro if I don't know the value beforehand.

Does anyone know how I can fix this, or if there is an alternative to this?

6
  • 2
    You have a much worse problem than the compiler error: You return a pointer to a local variable. Local variables go out of scope once function returns, and that will leave you with a stray pointer to an array that no longer exist. Attempting to dereference the returned pointer will lead to undefined behavior. Commented Nov 11, 2017 at 2:38
  • 1
    On another unrelated note, there is a case in which the strncpy will not add the terminator. Look out for that. Commented Nov 11, 2017 at 2:40
  • Once you pass an array to a function it decays to a pointer. At that point sizeof tells you the size of the pointer, not the length of the array. If it is a null terminated string you could use strlen to find the length of the content, but that may not be the length of the actual array. stackoverflow.com/questions/492384/… Commented Nov 11, 2017 at 2:59
  • @Someprogrammerdude: It is actually the lifetime of the newArray object that matters, not the scope of its name. Scope is where a name is visible. Lifetime is when an object exists. Commented Nov 11, 2017 at 3:52
  • By the way, I suspect the OP is not compiling this with a modern standard C version. I do not see any expression in their code that would generate that error about a constant value. But, if they are using a version of C that does not support variable length arrays, they would get that error on the newArray declaration because it uses a run-time value for the dimension. So the reason the OP got the error is actually unrelated to the fact that sizeof(array) does not produce the size of the “array.” Commented Nov 11, 2017 at 3:58

2 Answers 2

4

It's because passing an array to a function actually passes a pointer, so sizeof is giving you the size of a pointer instead of the size of the array, a simple solution is

char *test(char *array, size_t current_size, size_t expand_size)
{
    char string[current_size + expand_size + 1];
    // Rest of your code
}

But then, it would be a mistake to return the array string from this function, as it's only valid within the function.

I think you need to read about memory allocation, arrays and pointers before you continue your coding in c, because it's clear that you don't have the required knowledge yet.

Also, in general you should avoid strncpy() because a null terminator is not guaranteed with that function, it turns out to be very easy to end up with a non-null terminated array that you will assume is a string but it's of course, not.

Sign up to request clarification or add additional context in comments.

Comments

0

I find two errors in your code.

First, passing an array to a function is exactly passing a pointer to the first element in the array. So sizeof(array)returns the size of a pointer, not the whole array.

Second, the array in a function is stored in a stack, it will be destroyed after the program left the function. You can't get anything but errors when returning an array which is created by char newArray[size].

Here is my code which may help you:

#include <stdlib.h>
#include <string.h>

char *NewArray(char arr[], int arr_size, int expand_size)
{
    int new_size = arr_size + expand_size;
    char *new_arr = malloc(sizeof(char) * new_size);
    strncpy(new_arr, arr, new_size * sizeof(char));

    return new_arr;
}

2 Comments

A minor note: You use sizeof(char) * new_size to calculate the size passed to malloc but only new_size for the size passed to strncpy. They are the same with char, of course, but it might be nice to use the same style in both places—either use sizeof(char) * new_size to make the sizing explicit and prominent in case the type is ever changed or use new_size in both places for brevity. Or perhaps sizeof *arr * new_size so the size automatically changes if the array type is ever changed.
"You can't get anything but errors when returning an array which is created by char newArray[size]" True, but the OP does not do this, so why mentioning it?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.