函数返回局部变量的地址,用c表示

时间:2014-03-31 16:25:44

标签: c

在main()类(进程请求结束)

之前,我的返回ret继续出错
buddy.c: In function `process_request':
buddy.c:89: warning: function returns address of local variable

我收到错误,我尝试做的是将我从process_request获得的结果打印到main()函数末尾附近的打印,帮助?

//used a flag 
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

#define F_SIZE 2
#define A_SIZE 2
#define BUDDY_SIZE 4*1024       // in bytes
            // compile using gcc-o buddy buddy.c -lm

            // block information
struct block_info
{
    char AF_flag;               // flag
    int data;                   // data in the block
};

typedef struct block_info block;

block buddy_block[BUDDY_SIZE];  // entire buddy system to be used in this array
int block_count = 0;            // number of blocks in buddy_block

int get_block_size(int num)
{
    int i = 0;

    for (i = 0; num < pow(2.0, (double)i); ++i);
    return (int)(pow(2.0, (double)i));
}

char *process_request(char *s, int len)
{
    block b;
    block n;
    int i, j, count, block_size = 0;
    int first_buddy_size = 0;
    int second_buddy_size = 0;
    char ret[BUDDY_SIZE] = { 0 };
    char *response[BUDDY_SIZE] = { 0 };

    if (!s)
        return NULL;
    first_buddy_size = buddy_block[0].data;
    second_buddy_size = buddy_block[1].data;
    block_size = get_block_size(atoi(s));
    // get the matching FREE block in the power of 2

    if (*s == 'A')
    {                           // Allocation request
        int i = 0;
        char *buff = NULL;

        // split the block
        char strf[F_SIZE] = { 0 };
        char stra[A_SIZE] = { 0 };
        strf[0] = 'F';
        stra[0] = 'A';
        for (i = 0; block_size <= first_buddy_size / 2; ++i)
        {
            first_buddy_size /= 2;
            sprintf(buff, "%d", first_buddy_size);
            response[i] = strcat(strf, buff);
        }
        sprintf(buff, "%d", block_size);
        response[i] = strcat(stra, buff);

        // update the array
        count = i;
        for (i = 0, j = count; j; --j, ++i)
        {
            char *str = response[j];

            buddy_block[i].AF_flag = *str++;
            while (*str)
                buddy_block[i].data = *str;
        }
    }

    else if (*s == 'F')
    {                           // Free request
        for (i = 1; i < block_count; ++i)
        {                       // traversing through the array
            if (buddy_block[i].data = block_size)
            {                   // b.AF_flag = 'B';
                i << 1;

            }
        }
    }
    // update array
    count = i;
    for (i = 0, j = count; j; --j, ++i)
    {
        char *str = response[j];

        buddy_block[i].AF_flag = *str++;
        while (*str)
            buddy_block[i].data = *str;
    }

    return ret;                 // ------------error: warning functions returns address
                                // of local variable----------
}

int main(int argc)
{
    block t;
    int i;
    char ch;
    char *ret = NULL;
    char line[20];

    t.AF_flag = 'X';            // some junk means memory block not even accessed
    t.data = 0;

    for (i = 0; i < BUDDY_SIZE; i++)
        buddy_block[i] = t;     // initialize with 0 bytes and no information about
                                // Allocation/Free

    // initially there is only one Free block of 4K bytes
    t.AF_flag = 'F';
    t.data = BUDDY_SIZE;
    buddy_block[0] = t;         // started the buddy block to 4096 bytes, all free to be
                                // allocated
    ++block_count;

    while (1)
    {
        // get user input
        char request[5] = { 0 };    // 'F4096' or 'A4096', max 5 chars
        int correct_input = 0;
        char ch;

        for (i = 0, ch = 'X'; ch != '\n'; ++i)
        {
            ch = getchar();
            if ((i == 0) && (ch != 'A' || ch != 'F'))
            {
                printf("Illegal token!!! : should be A or F");
                correct_input = 0;
                break;
            }
            if (ch < '0' && ch > '9')
            {                   // illegal code
                printf("Illegal token!!! : should be 0 and 9");
            }
            correct_input = 1;
            request[i] = ch;
        }
        if (correct_input)
        {
            // process user input
            ret = process_request(request, sizeof(request));
            printf("%d", ret);  // [512](512A)(128A)(128F)(256F)(1024F)(2048F)
                                // //fprintf(stderr, "I am in stderr");
            fflush(stdout);
        }
    }
    return 0;
}

3 个答案:

答案 0 :(得分:4)

您已在堆栈上分配ret。虽然不禁止返回一个地址,但是后来调用的任何函数都会重用该堆栈,从而覆盖该地址的任何内容。

您可能需要考虑将此数据移动到调用者的堆栈或动态内存中。

char * foo() {
    char string[] = "Hello world\n";

    return string;
}

int main () {
    printf("%s", foo());
}

很可能打印"Hello World!"

一种正确的方法是:

void foo(char * buffer) {
    memcpy(buffer, "Hello world\n", sizeof("Hello world\n"));
}

int main () {
    char buffer[100];
    foo(&buffer);
    printf("%s", buffer);
}

或者使用动态内存(容易出现内存泄漏):

char * foo() {
    char * string = malloc(sizeof("Hello world\n"));
    memcpy(string, "Hello world\n", sizeof("Hello world\n"));

    return string;
}

int main () {
    char * string = foo();
    printf("%s", string);
    free(string);
}

答案 1 :(得分:4)

这正是它所说的。你在做什么

char* process_request(char*s, int len) {
    ...
    char ret[BUDDY_SIZE] = {0};
    ...
    return ret;
}

ret是内存位置的地址。问题是这样的内存位置指向局部变量。局部变量位于堆栈中,当您调用新函数时,其内存可能(可能会)重用于其他变量。

为避免这种情况,请返回指向已动态分配的内存位置的指针(即malloc和朋友)。

答案 2 :(得分:0)

您正在从函数返回一个本地指针,这是一个未定义的值。

char ret[BUDDY_SIZE] = {0};

所以,你的编译器抛出了这个错误。动态分配指针,错误就会消失。