简体   繁体   中英

Is it safe to pass address of char pointer to point to local array variable

Actually in the below program, I am trying to get reason by passing addr of pointer. According to stack concept, the local variables in the stack frame got destroyed upon the frame execution. So my question is how buffer[100] declared within the function is still accessible from main(). I just confused. Anyways I got the desired output.

#include <stdio.h>
#include <string.h>

#define TCP_SYSLOG_MANUAL_BLOCK "TCP syslog manual blocking enabled"
#define TCP_SYSLOG_MSQ_QFULL "TCP syslog message Queue full"
#define TCP_SYSLOG_HOST_DOWN "TCP Syslog server is DOWN"

void get_server_unreach_reason(char **reason)
{
        char buffer[100];
        printf("start addr of Buffer : %p\n", buffer);

        strncpy(buffer, TCP_SYSLOG_MANUAL_BLOCK, strlen(TCP_SYSLOG_MANUAL_BLOCK));
        printf("Buffer : %s\n", buffer);

        strcat(buffer, ", ");
        strncat(buffer, TCP_SYSLOG_MSQ_QFULL, strlen(TCP_SYSLOG_MSQ_QFULL));
        printf("Buffer : %s\n", buffer);

        strcat(buffer, ", ");
        strncat(buffer, TCP_SYSLOG_HOST_DOWN, strlen(TCP_SYSLOG_HOST_DOWN));
        printf("Buffer : %s\n", buffer);

        *reason = buffer;
}
int main()
{
        char *reason;
        get_server_unreach_reason(&reason);
        printf("reason pointing addr : %p\n", reason);
        printf("reason : %s\n", reason);
        return 0;
}

Output:

[revarath@bgl-vms-vm0251 basic]$ ./a.out
start addr of Buffer : 0x7ffe4efb2780
Buffer : TCP syslog manual blocking enabled
Buffer : TCP syslog manual blocking enabled, TCP syslog message Queue full
Buffer : TCP syslog manual blocking enabled, TCP syslog message Queue full, TCP Syslog server is DOWN
reason pointing addr : 0x7ffe4efb2780
reason : TCP syslog manual blocking enabled, TCP syslog message Queue full, TCP Syslog server is DOWN

Ok, Now I got your point. Shall you please suggest the below code is fine.

void get_server_unreach_reason(char *buffer, int buflen)
{
        ....
        strncpy(buffer, TCP_SYSLOG_MANUAL_BLOCK, strlen(TCP_SYSLOG_MANUAL_BLOCK));
        printf("Buffer : %s\n", buffer);

}
int main()
{
        char reason[100];
        get_server_unreach_reason(reason, sizeof(reason));
        ....
}

If fine, I got one more question. Suppose if we are calling get_server_unreach_reason() from different places(callers), then in all caller locations do we have to statically allocate the buffer before passing to function.

No.

The pointer returned from the function is invalid because the memory it points to no longer exists.

It may seem to work, but this is purely coincidental. This sort of misuse can blow up in your face when you least expect it, or more typically, in the face of an important customer.

You need to declare the local variable char buffer[100]; char buffer[100]; to make it work, but be aware that any call to the function will return the same pointer.

"So long as the stack frame is still out there," the answer would be "yes."

But, I'll be the first to say that you should not do this: nothing(,) is more awful to debug than "something that 'scribbles the stack.'" If you want to pass-around "the pointer to something," let that "something" always(!) be something that you expressly allocated from the heap.

Sure: "if this really is a one-time function call that's gonna call and come right back, and nothing is going to try to remember the pointer-value that you supplied," no problem. But - I have been burned too many times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM