簡體   English   中英

我的 C 編程生疏了,我遇到了一些問題

[英]My C programming is rusty and i'm having some issues

我試圖在 c 中聲明一個數據結構並設置一些變量,但我遇到了一些麻煩。

struct point {
   float *x;
   float *y;
   float *z;
};

這個結構有 24 個字節長,所以我覺得沒問題。

const unsigned int sz = 1<<24;
struct point _points[sz];

for(int i = 0; i < sz; ++i)
{
    _points[i].x = get_rand_float(); 
    _points[i].y = get_rand_float();
    _points[i].z = get_rand_float();
}

// get_rand_float() returns a pointer to float;

我遇到的問題是應用程序會崩潰。

我玩了一下代碼,似乎 1<<24 太大了? 將它降低到 1<<14 程序運行得很好。

這讓我想到了另一個問題,為什么 1<<24 或大約 1600 萬個整數會導致我的程序崩潰? 這是一個相當簡單的程序,只是 int main 樣板和這個結構?

在您的代碼中, szint變量,而不是數組。 因此,從技術上講,您不能在sz上使用數組下標運算符。 該代碼不應該編譯。

也許,你想寫一些類似的東西

 _points[i].x = get_rand_float();

但話又說回來,它取決於get_rand_float()返回類型。 它必須返回一個float * (這不太可能看到函數名稱)。

如果get_rand_float()返回一個float,並且您想存儲返回的值,那么您不需要使用指針作為結構成員變量。 您可以簡單地使用float x; 等等。

你不想要一個指向浮點數的指針結構:

struct point {
   float *x;
   float *y;
   float *z;
};

你想要一個浮點結構:

struct point {
   float x;
   float y;
   float z;
};

編輯:根據您的編輯,當您使用大量結構大小(1<<24)或結構中的 16,777,216 個項目時,會發生崩潰。 從這里借用一個答案:

C結構的尺寸限制

通過在對象中包含超過 65535 個字節,您似乎違反了 C 標准。 由於 1<<14 有效,只有 16384,這可能就是原因。 要進行驗證,請嘗試使用 1<<16 以上的任何值 - 這些都應該會崩潰,因為它會超過 65535。

附帶說明一下,如果您發布實際收到的錯誤消息會很有幫助,這樣我們就可以更好地了解發生了什么。 :)

---前作者編輯答案---

假設 get_rand_float() 返回它應該返回的內容,問題是 sz 是一個 int,而不是一個結構。 它應該看起來像:

int sz = 24;
struct point _points[sz];

for(int i = 0; i < sz; ++i)
{
    _points[i].x = get_rand_float(); 
    _points[i].y = get_rand_float();
    _points[i].z = get_rand_float();
}

分開數組的大尺寸,您的程序主要是崩潰,因為沒有分配給指針變量 x、y 和 z 的內存。 在分配任何值之前,您必須為變量分配內存。

for(int i = 0; i < sz; ++i)
{
    sz[i].x = get_rand_float(); <--- getting crash here!
    sz[i].y = get_rand_float();
    sz[i].z = get_rand_float();
}

for(i=0;i<sz;i++)
    {
        _points[i].x =(float *) malloc(sizeof(float));
        _points[i].y = (float *) malloc(sizeof(float));
        _points[i].z = (float *) malloc(sizeof(float));
       *( _points[i].x) = get_rand_float();
       *( _points[i].y) = get_rand_float();
       *( _points[i].z) = get_rand_float();
    }
    for(i=0;i<sz;i++)
    {
        printf("%f %f %f ",*( _points[i].x), *(_points[i].y), *(_points[i].z));
        printf("\n");
    }

您可以通過將浮點數作為結構成員而不是浮點數指針來簡化程序。

struct point {
   float x;
   float y;
   float z;
};
int main()
{
    int i;
    for(i=0;i<sz;i++)
    {
        _points[i].x = get_rand_float();
        _points[i].y = get_rand_float();
        _points[i].z = get_rand_float();
    }
    for(i=0;i<sz;i++)
    {
        printf("%f %f %f ", _points[i].x, _points[i].y, _points[i].z);
        printf("\n");
    }

其他人指出了您的兩個主要問題(尺寸太大,您應該在結構中使用 float 而不是 float* )。 但是還有另一個潛在的問題:您不應該養成以下划線開頭的標識符名稱的習慣,因為,從 1999 C 標准的第 7.1.3 節開始:

  • 所有以下划線和大寫字母或另一個下划線開頭的標識符始終保留供任何使用。

  • 所有以下划線開頭的標識符始終保留用作普通名稱空間和標記名稱空間中具有文件范圍的標識符。

  • 以下任何子條款(包括未來的庫方向)中的每個宏名稱都保留供指定的使用,前提是包含任何關聯的頭文件; 除非另有明確說明(見 7.1.4)。

  • 以下任何子條款(包括未來的庫方向)中具有外部鏈接的所有標識符始終保留用作具有外部鏈接的標識符。 154

  • 在以下任何子條款(包括未來的庫方向)中列出的每個具有文件范圍的標識符都被保留用作宏名稱,如果包含任何關聯的標題,則保留用作相同名稱空間中具有文件范圍的標識符。

一個可能的問題是您的點數組對於堆棧來說太大了。 這里 您可以通過動態內存分配來解決這個問題,例如:

struct point *_points = malloc(sz*sizeof(struct point));

當然,完成后不要忘記釋放內存。

暫無
暫無

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

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