简体   繁体   English

函数在c中返回局部变量的地址

[英]Function returns address of local variable, in c

Keep getting an error on my return ret before the main () class (end of process request) 在main()类之前(流程请求结束),我的返回ret上始终出现错误

buddy.c: In function `process_request':
buddy.c:89: warning: function returns address of local variable

Error I receive , what I'm trying to do is print the results I get from my process_request to my print near the end of my main() function, help? 我收到错误消息,我要执行的操作是将从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;
}

You have allocated ret on the stack. 您已经在堆栈上分配了ret Although it is not forbidden to return an address to that the stack will be reused by any function that is called afterwards thus overwriting whatever was at that address. 尽管不禁止将地址返回到该地址,否则该堆栈将被随后调用的任何函数重用,从而覆盖该地址上的所有内容。

You may want to consider moving this data onto the caller's stack or into dynamic memory. 您可能需要考虑将这些数据移动到调用者的堆栈或动态内存中。

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

    return string;
}

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

Will most likely not print "Hello World!" 很可能不会打印"Hello World!" .

One right way would be: 一种正确的方法是:

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

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

Or with dynamic memory (prone to memory leaks): 或带有动态内存(容易出现内存泄漏):

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);
}

It means exactly what it says. 这就是说的意思。 You are doing 你在做

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

ret is an address to a memory location. ret是存储位置的地址。 The issue is that such memory location points to a local variable. 问题是这样的内存位置指向局部变量。 A local variable lies in the stack, and its memory may be (probably will) reused for other variables when you call new functions. 局部变量位于堆栈中,当您调用新函数时,它的内存可能(可能会)被其他变量重用。

To avoid that, return a pointer to a memory location that has been dynamically allocated (that means malloc and friends). 为了避免这种情况,请返回一个指向已动态分配的内存位置的指针(这意味着malloc和friends)。

You are returning a local pointer from a function and that is an undefined value. 您正在从函数返回一个本地指针,这是一个未定义的值。

char ret[BUDDY_SIZE] = {0};

SO, your compiler is throwing that error. 因此,您的编译器将抛出该错误。 Assign your pointer dynamically and the error should go away. 动态分配指针,该错误应消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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