2014-03-31 54 views
-1

保持在main()类(处理请求结束)函数返回局部变量的地址,在C

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

错误我收到之前让我的回报RET一个错误,我想要做的在main()函数的结尾处打印我从process_request获得的结果到我的打印结果中,有帮助吗?

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

回答

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

您从一个函数返回一个局部指针和为不定值。

char ret[BUDDY_SIZE] = {0}; 

因此,您的编译器正在抛出该错误。动态分配指针,错误应该消失。

4

这意味着它的意思。你正在做

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

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

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

相关问题