簡體   English   中英

結構體中數組的C Malloc

[英]C Malloc of array within a struct

我正在嘗試使用main值分配一個結構。 我一直在尋找實現的方法,但是找不到答案。 我有3種硬幣我想投入RET其價格的。 我如何申報RET從結構?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

typedef struct
{

    double *ret;

}coin;


void ini(int a)
{
    ret = (double*)malloc(a*sizeof(double));
}


int main(void){

    long int a=250;
    int n_coins=3;


        coin *m = (coin*)malloc(n_coins*sizeof(coin));

        ini(a);

        m[0].ret[0] = 2000;
        printf("%lf", m[0].ret[0]);



    return 0;
}

首先, return是C中的保留keyword ,您不能將保留關鍵字用作變量名。

其次,如果要在其他函數中為任何數據類型的數組分配內存,則在該函數中聲明一個變量,調用malloc ,通過malloc分配所需的空間並返回已分配空間的第一個元素的地址。返回被調用函數(這里的main() )不知道分配的空間的地址,並且它無法訪問分配的內存空間。您可以這樣執行:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

typedef struct
{
   double *var;
}moeda;


double *ini(int n)
{
   double *arr;
   arr = malloc(n*sizeof(*arr));
   return arr;
}

int main(void){

   long int a=250;

    moeda m;

    m.var=ini(a);

    m.var[0] = 2000;
    printf("%lf", m.var[0]);



    return 0;
}

如果我有您的代碼並必須對其進行改進,我會爭取

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

// The kernel style guide https://www.kernel.org/doc/html/v4.10/process/coding-style.html discourages typedefs for structs
typedef struct moeda {
    double *return_value;
} moeda;


// return a struct here:
moeda initialize_return(int a)
{
    moeda ret;
    ret.return_value = malloc(a*sizeof(double));
    return ret;
}


int main(void) {
    long int a=250;

    moeda m = initialize_return(a);

    m.return_value[0] = 2000;
    printf("%lf", m.return_value[0]);

    return 0;
}

(最好將所有標識符都用英語表示)。

這將是第一步。 然后我可能會意識到並不需要該結構,並替換它:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

double * initialize_double_array(int a)
{
    return malloc(a*sizeof(double));
}

int main(void) {
    long int a=250;

    double * arr = initialize_double_array(a);

    arr[0] = 2000;
    printf("%lf", arr[0]);

    return 0;
}

OTOH,如果在所述結構中還有其他字段,我可能會決定是否應該將它們與該數組一起初始化。

一些變體:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

// The kernel style guide https://www.kernel.org/doc/html/v4.10/process/coding-style.html discourages typedefs for structs
struct moeda {
    int num_values;
    double *values;
};

// only fill a struct here:
// i. e. take a pre-initialized struct and work with it:
void moeda_alloc_values(struct moeda * data) 
{
    data->return_value = malloc(data->num_values * sizeof(double));
}

// return a struct here:
struct moeda initialize_moeda(int num) 
{
    struct moeda ret;
    ret.num_values = num;
    ret.return_value = malloc(num * sizeof(double));
    // or just moeda_alloc_values(&ret);
    return ret;
}

int main(void) {
    long int a=250;

    struct moeda m = initialize_return(a);
    m.return_value[0] = 2000;
    printf("%lf", m.return_value[0]);

    struct moeda m2;
    m2.num_values = 20;
    moeda_alloc_values(&m2);
    m2.return_value[0] = 2000;
    printf("%lf", m2.return_value[0]);

    return 0;
}

struct返回函數的優點是返回后具有“立即填充”的結構。

另一個通過指針修改結構的函數的優點是,它可以在任何可能預先填充的,可能已分配的結構上工作,並且可以在單個字段上工作,而不必考慮所有字段。

return是c中的關鍵字。 您不能將其用作變量名。 我也不清楚這個問題。 什么是“ moeda m”? 萌達在這里? 如果這不是英語C,我很抱歉。

我假設您只是意味着您正在嘗試從main中調用的函數向結構分配內存。 為了清楚起見,我更改了您的變量名。 因此,首先,正如其他人所說,您不能將return用作變量名。 我還建議您使用結構的大小,而不是僅使用兩倍,因為將來您在結構中可能會有多個變量。

如果要使用main函數,則必須將指針傳遞給該函數,然后使用malloc為該函數分配內存,然后返回它。 或者,您可以將struct指針設置為全局選項。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "stdafx.h"
#include <malloc.h>

typedef struct
{
    double number;
}example;

example *allocateMemory(int a, example *s)
{
    s = (example*)malloc(a * sizeof(example));
    return s;
}

int main() {

    long int a = 250;
    example *structure = NULL;
    structure = allocateMemory(a, structure);

    structure[0].number = 2000;

    printf("%lf\n", structure[0].number);

    //cleaning up memory
    free(structure);
    structure = NULL;
    return 0;
}

只是其他一些說明,我讓我的示例結構等於null,因為編譯器抱怨未初始化的局部變量。

在您的代碼中,您有這個。

m.retorno[0] = 2000;

但我假設您想訪問struct數組中的第一個數字,因此應該是:

structure[0].number = 2000;

對於此特定示例,我將執行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

typedef struct
{
   size_t  nLen;    // number of elements allocated for var
   double *var;     // pointer to a list of double variables
} moeda;

// struct is small so just initialize the whole thing and return it
// from the initialization routine.
moeda iniMoeda (size_t n)
{
   moeda x = {0};

   x.var = malloc(n * sizeof(double));   // try to allocate the requested number of doubles
   if (x.var) x.nLen = n;     // if allocated then remember number of doubles

   return x;
}

// free a moeda variable. we require a pointer so that we can reset
// the moeda variable to a known state of NULL pointer and zero allocation
// length so that we can easily catch using the variable after the memory
// has been freed. Hope for Address exception on a NULL pointer if this
// variable is used after freeing.
void freeMoeda (moeda *x)
{
    // free the allocated doubles and clear everything.
    // if x->var is NULL then free() does nothing.
    free (x->var); x->var = NULL; x->nLen = 0;
}

int main(void)
{
    size_t  a = 250;
    moeda   m = iniMoeda (a);

    if (m.var) {
        // allocation worked so lets test our space
        m.var[0] = 2000;
        printf("%lf", m.var[0]);
    } else {
        printf ("m.var is NULL.\n");
    }

    freeMoeda (&m);
    return 0;
}

以下建議的代碼:

  1. 干凈地編譯
  2. 說明為什么包含每個頭文件
  3. 執行所需的操作
  4. 自我清理后
  5. 包含有關代碼中每個步驟的嵌入式注釋

注意:代碼必須一致,可讀並執行所需的功能

現在,建議的代碼:

// for ease of readability and understanding:
// 1) insert a space:
//    after commas,
//    after semicolons,
//    inside brackets,
//    inside parens,
//    around C operators
// 2) separate code blocks
//    ( 'for' 'if' 'else' 'while' 'do...while' 'switch' 'case' 'default' )
//    via a single blank line
// 3) variable (and parameter) names should indicate
//    'content' or 'usage' (or better, both)

#include <stdio.h>   // printf(), perror()
#include <stdlib.h>  // malloc(), free(), exit(), EXIT_FAILURE
// do not include header files those contents are not used
//#include <math.h>
//#include <string.h>

// added 'sCOIN' tag name to make it easier to use debugger
// since most debuggers use the tag name to reference fields inside a struct
typedef struct  sCOIN
{
    double *ret;
} coin;


int main( void )
{
    // 'malloc()' expects its parameters to be of type 'size_t'
    size_t n_coins=3;
    coin  mycoin;

    // do not cast the returned value from 'malloc()', 'calloc()', 'realloc()'
    // as the returned type is 'void*' which can be assigned to any pointer
    //coin *m = (coin*)malloc(n_coins*sizeof(coin));
    mycoin.ret = malloc( n_coins * sizeof( double ) );
    // always check to assure the operation was successful
    if( !mycoin.ret )
    {
        // 'perror()' outputs the enclosed text
        // and the text of why the system thinks the error occurred
        // to 'stderr'
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    // the field in 'coin' is declared a DOUBLE so assign a double
    // not a integer.  I.E include a decimal point '.'
    mycoin.ret[ 0 ] = 2000.0;
    printf( "%lf", mycoin.ret[ 0 ] );

    // code should always clean up after itself
    // I.E. don't leave a mess nor depend on the OS to cleanup.
    free( mycoin.ret );
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM