2014-03-31 99 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和朋友)。

相關問題