0

I want to return the result of a function through the pointer *address, given as parameter. My code below prints this output:

Result:

But I was expecting:

Result: 123456

Why isn't it working as expected?

#include <stdio.h>

static void get_address(char *address) {
    address = "123456";
}


int main(int argc, const char * argv[]) {

    char address[34];
    get_address(address);
    printf("Result: %s\n",address);

    return 0;
}
eztam
  • 3,443
  • 7
  • 36
  • 54
  • `address` in get_address is a local pointer to `address` in main. Changing the pointer has no effect on main. – stark Nov 10 '21 at 14:09
  • In C all arguments are pass *by value*. That means when you call a function, the arguments value is *copied* into the local argument variable of the function. Modifying this copy in any way (like assigning to it) will not change the original value. – Some programmer dude Nov 10 '21 at 14:10
  • I'm fairly sure this is a duplicate. In a nutshell, `get_address` is passed the address of the array of 34 characters in `main` in a **copy** of the pointer. It changes the copy so that it points at the constant array of characters "123456" but the variable of the same name in `main` is not altered. It doesn't help that you gave the parameter passed to `get_address()` the same name as a local variable in `main()` – Tim Randall Nov 10 '21 at 14:11
  • You probably want this: `static void get_address(char* address) { strcpy(address, "123456"); } `. And don't forget `#include – Jabberwocky Nov 10 '21 at 14:11
  • Furthermore, your premise is wrong, you essentially try to assign to an array, which isn't possible. You can only *copy* to an array. And from this it should be easy to figure out how to solve your problem: You need to *copy the string into `address`*. With e.g. `strcpy`. – Some programmer dude Nov 10 '21 at 14:11
  • You would need to use `strcpy()` or `strncpy()` to change the content of the array `address`. There is nothing you can do to change the value of the array itself. The identifier `address` in `char address[34];` cannot be assigned another value. – Weather Vane Nov 10 '21 at 14:11
  • See this: [Dynamic memory access only works inside function](https://stackoverflow.com/questions/39486797/dynamic-memory-access-only-works-inside-function). Not an exact duplicate but close. – Lundin Nov 10 '21 at 14:13

2 Answers2

2

'address' in get_address gets a copy of the address of the start of the array address in main(). get_address changes that local pointer to the address of the local string "123456" and then does nothing with it. What you meant to do is probably the following:

#define DEST_BUFFER_SIZE  34
static void get_address(char* address) {
    const char str[] = "123456";
    strcpy_s(address, DEST_BUFFER_SIZE, str);
}

int main(int argc, const char * argv[]) {
    char address[DEST_BUFFER_SIZE];
    get_address(address);
    printf("Result: %s\n", address);
    return 0;
}

Here strcpy_s is the safe version of strcpy and is used to copy the contents of the local str char-array to the memory location specified by address in get_address.

Eddie
  • 36
  • 3
  • 1
    It isn't safe to use the length of the *source* to restrict the copy. The `strcpy_s()` will be restricted by the length of `str` anyway. It should be given the size of the *target* space, which the function as written does not know. If the original string had been `char address[4];` it would fail. – Weather Vane Nov 10 '21 at 14:35
  • @WeatherVane Thanks for the feedback. Recall that `strcpy_s` requires string length (https://en.cppreference.com/w/c/string/byte/strcpy). I have compiled and tested this, and this version gives the desired output (in VS2019). Within the context of the current example, it is ok because `address` has sufficient space and the string to be copied is smaller than the capacity. If we were talking in general, we would have to add additional mechanisms to ensure safety. – Eddie Nov 11 '21 at 05:57
  • No, it requires the size of the *destination*. The danger of `strcpy` is that the source string overruns the target buffer (whether or not the source string is nul terminated). That argument of [`strcpy_s`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170) is named `dest_size` by MS and `destsz` in your link. I suggest you try with a buffer that is too small, for example `char address[4];` and see if it is still safe. It was pointless using the length of the source string a sa safeguard, because `strcpy_s` is going to stop there anyway. – Weather Vane Nov 11 '21 at 06:48
  • As long as the length of the input parameter is given less than the buffer-capacity it is fine. As I said in my previous comment, this worked without any problem within the context of the stated question. İn the question the buffer length is sufficiently large, and the length of the source string is correctly given in my code (including the null-terminator character). Again -as I stated in my answer to your first comment- the case where buffer-length is not sufficient is a general case and there is no explicit statement in the question regarding such general a case. Thanks for your concern. – Eddie Nov 11 '21 at 07:36
  • 1
    @WeatherVane Ok, I think we have been looking at the problem from different sides. You probably want to point out to the correct usage of strcpy_s. I have edited the code as you suggested and checked, it works. Thanks! – Eddie Nov 11 '21 at 11:48
-1
#include <stdio.h>

static void get_address(char *address) {
     //Attention here
     // use the reference operator
     // (in your code you were affecting to the address of the variable not it's content)
    *address = "123456";
}