2017-04-21 109 views
0

返回一个二维结构,这是我如何声明这个结构我怎样才能解决这个当我尝试从功能

typedef struct cache{ 
int vaild; 
char* tag; 
char* data; 
}cache; 

这是我的主要的一部分调用此函数

struct cache **cacheA = createCache(Setnum,(int)pow(2,blocksize),cachesize); 
struct cache **cacheB = createCache(Setnum,(int)pow(2,blocksize),cachesize); 

现在这是我所谓的功能

struct cache ** createCache(int numset, int blocksize, int cachesize){ 
    int numcache = (int)((cachesize/blocksize)*numset); 
    struct cache out[numset][numcache]; 
    int i,j; 
    for (i=0; i < numset; i++){ 
     for (j=0; j < numcache; j++){ 
      out[i][j].tag = "0"; 
      out[i][j].vaild = 0; 
      out[i][j].data ="0"; 
     } 
    } 
    return out; 
} 

,当我尝试编译此,它告诉我,

return from incompatible pointer type 
function returns address of local variable 

(指向行“返回了;”)

我不知道什么是错我的代码,我的意思是函数返回的类型是一样的,我怎么declear“走出去” ,那么是什么原因导致这个问题?

+2

'out'是本地的'createChache'的范围,如果返回一个指向它,指针会叼着它返回'out'将有一刻被摧毁。 –

+0

另一个提到的问题是struct cache **与struct cache cache [numset] [numcache]不是同一类型的对象;' –

回答

0

您创建struct cache out[numset][numcache];
范围内的函数原型为:struct cache ** createCache(...)
然后尝试返回out

这是因为struct cache [][]的输入方式与struct cache **的输入方式不同,您将收到返回错误。 1)如果你确实想要一个指向结构体指针的指针,那么malloc或calloc需要在某个时刻用来分配内存。
2)在分配值之前,结构的char *成员也需要分配内存。如下图所示,它们更改为char []
3)通过使用=赋值运算符为字符串赋值不起作用。使用字符串函数,如strcpy,sprintf等。
4)您已使用与您创建的新类型相同的符号命名该结构,即cache。在此应用程序中,名称缓存不是必需的。另外,纯粹为了风格,我在CAPS中展示了新的类型。 这不是必需的,但只是一种我用来使代码中的新类型更易识别的样式。

鉴于上述评论的,该结构可以改变为以下内容:

typedef struct { /// don't need name here when it in this application 
    int vaild; 
    //char *tag; 
    char tag[20];//for illustration, to avoid additional dynamic allocation of memory 
    //char* data; 
    char data[80]; 
}CACHE;//capitalization is style only, not a necessity here. 

注意,没有名字,但新类型CACHE已创建。现在,您可以创建功能createCache:

CACHE ** createCache(int ncache, int nset)//note for simplicity of freeing this 
              //object later, simplify number of arguments 
{ 
    CACHE **out; 
    out = calloc(ncache, sizeof(CACHE *));//create array of pointers to CACHE 
    if(!out) return NULL; 
    int i; 
    for (i=0; i < nset; i++) 
    { 
     out[i] = calloc(nset, sizeof(CACHE));//create space for each instance 
              //of CACHE pointed to by array pointers 
    } 
    return out; 
} 

任何时间内存在堆上创建的,它需要被释放。此方法将释放缓存对象存储:

void freeCashe(CACHE **a, int nset) 
{ 
    int i; 
    for(i=0; i<nset; i++) 
    { 
     if(a[i])free(a[i]); 
    } 
    if(a)free(a); 
} 

调用这些函数,如下所示,将创建一个指针数组,每个指向的CACHE一个实例,其中可以使用它们按预期运行,然后释放所有的内存完成后:

int main(void) 
{ 
    int cachesize = 20; 
    int blocksize = 20; 
    int numset = 10; 
    //move the calculation out of creation function 
    //to simplify freeing object later. 
    int numcache = (int)((cachesize/blocksize)*numset); 

    CACHE **a = createCache(numcache, numset); 
    /// use a, then free a 
    freeCashe(a, numset); 

    return 0; 
} 
0

你的函数需要在堆上分配内存而不是堆栈。你需要在堆上为你的指针数组和空间分配空间。

struct cache ** createCache(int numset, int blocksize, int cachesize){ 
    cache ** out; 
    int numcache = (int)((cachesize/blocksize)*numset); 
    size_t headerSize = sizeof(*out)*numset; 
    size_t bodySize = sizeof(**out)*numcache; 
    out = malloc(headerSize + (bodySize*numset)); 
    if (out == NULL) { 
     /* Should probably output some message about being 
     * insufficient memory here. */ 
     return NULL; 
    } 

    int i,j; 
    for (i=0; i < numset; i++){ 
     /* need to assign our point */ 
     out[i] = (cache*)(((char*)out)+(headerSize+bodySize*i)); 
     for (j=0; j < numcache; j++){ 
      out[i][j].tag = "0"; 
      out[i][j].vaild = 0; 
      out[i][j].data ="0"; 
     } 
    } 
    return out; 
} 

/* importantly, you want a way to free your allocated memory */ 
void destroyCache(cache ** ptr) { 
    free(ptr); 
} 

PS:你没有,如果你与struct关键字引用它来typedef你的结构。

0

你想要一个指针指针类型被返回,但为了做到这一点,你需要动态分配它。本地堆栈分配(即struct cache [x] [y])将不起作用。尝试使用2D阵列时,您会得到一个错误或者程序崩溃。

解决方案是预先分配空间并将其传递给函数或在函数本身中进行分配。

分配在功能例:

struct cache ** createCache(int numset, int blocksize, int cachesize){ 
    int numcache = (int)((cachesize/blocksize)*numset); 

    struct cache **out = malloc(sizeof(struct cache *) * numset); // This line changed. 
    int i,j; 
    for (i=0; i < numset; i++){ 

     out[i] = malloc(sizeof(struct cache) * numcache); // This line added. 

     for (j=0; j < numcache; j++){ 

      out[i][j].tag = malloc(sizeof(char)); // This line added. 
      out[i][j].data = malloc(sizeof(char)); // This line added. 

      strcpy(out[i][j].tag, "0"); 
      out[i][j].vaild = 0; 
      strcpy(out[i][j].data, "0"); 
     } 
    } 
    return out; 
} 
+0

不要忘记你必须最终释放你分配的所有东西。 – MrJman006