-2

I am trying to declare a data structure in c and set some variables but I'm having a bit of trouble.

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

this struct is 24 bytes long so that's fine by me.

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;

The problem that I am having is that the application will crash.

I playing with the code a bit it seems that maybe 1<<24 is too large? Bringing it down to 1<<14 the program runs just fine.

That brings me to another question, why would 1<<24 or about 16 million ints cause my program to crash? It's a fairly trivial program just int main boilerplate and this struct?

mr oh
  • 93
  • 9
  • Please edit your title to actually reflect the problem you're having, and please actually state the problem in your post. We don't know what "I'm having a bit of trouble" means right away. – Ricky Mutschlechner Jun 22 '15 at 16:00
  • 4
    You cannot get a crash on something that does not compile... – luk32 Jun 22 '15 at 16:00
  • *I'm having a bit of trouble* is not a meaningful problem description. Please [edit] your question to clearly explain what *trouble* you're having. While you're at it, you can edit the title of your post to something that also describes the problem you're having or the question you're asking in a way that will have meaning to a future reader here who finds it in a search result. Thanks. – Ken White Jun 22 '15 at 16:01
  • what compiler options are you using that will allow you to compile this program... (just for my curiosity not that it will help answer this) – Grady Player Jun 22 '15 at 16:02
  • I think - besides all the obbbvious - the issue is that in the point struct you have float* - either allocate or remove * (make it a variable not a pointer) – Mario The Spoon Jun 22 '15 at 16:02

6 Answers6

1

In your code, sz is int variable, not an array. So, techinicaly you cannot use the array subscript operator on sz. That code should not compile.

Maybe, you wanted to write something like

 _points[i].x = get_rand_float();

But then again, it depends on get_rand_float() return type. It has to return a float * (which is not very likely seeing the function name).

In case, if get_rand_float() returns afloat value, and you want to store the returned value, then you don't need to use pointers as your structure member variable. You can simply use float x; and so on.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

You don't want a structure of pointers to floats:

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

You want a structure of floats:

struct point {
   float x;
   float y;
   float z;
};
dlask
  • 8,776
  • 1
  • 26
  • 30
0

EDIT: Based on your edit, your crash occurs when you use a massive struct size (1<<24), or 16,777,216 items in the struct. Borrowing an answer from here:

Size limitation of C structure

It would appear that you may be violating C standard by having over 65535 bytes in an object. Since 1<<14 works, which is only 16384, that might be why. To verify, try using anything above 1<<16 - those should all crash because it would be over 65535.

On a side note, it would be helpful if you post the actual error message you get so we have a better idea of what is going on. :)

---Pre-Author Edit Answer---

Assuming get_rand_float() returns what it's supposed to, the problem is that sz is an int, not a struct. It should look like:

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();
}
Community
  • 1
  • 1
Glamdring
  • 75
  • 6
  • This answer was pretty helpful, it seems that I can go as high as 1<<19 at 1<<20 it crashes. So there's some memory limitations in c. Wouldn't this limit c's ability to do SoA programming? looking at the printed output the max_size is significantly larger. `size of 1<<19 is: 524288i max size: 18446744073709551615` – mr oh Jun 22 '15 at 21:13
  • I'm afraid that I would not be able to answer that; anyone else care to jump in on this? Not exactly the most familiar with SoA programming unfortunately. – Glamdring Jun 22 '15 at 21:18
0

Keeping apart the big size of the array,your program is mainly crashing because there no memory allocated to the pointer variables x,y and z. You have to allocate memory to the variables before assigning any values.

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

You can make your program simple by taking float as members of the structure instead of float pointers.

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");
    }
Rndp13
  • 1,094
  • 1
  • 21
  • 35
0

Others have pointed out your two main problems (size too large, and you should be using float not float* in your struct). But there is another potential problem, too: you should not get into the habit of beginning an identifier name with an underscore, because, from Section 7.1.3 of the 1999 C standard:

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

  • Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).

  • All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154

  • Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

FredK
  • 4,094
  • 1
  • 9
  • 11
  • The OP certainly shouldn't be using reserved identifiers, and that's worth pointing out, but it's vanishingly unlikely that that's the cause of the problem. – Keith Thompson Jun 22 '15 at 18:43
  • thank you, I read the reference and it's clear. I'll be make sure not to use this type of naming convention in the future. – mr oh Jun 23 '15 at 03:01
0

One possible problem is that your array of points is too large for the stack. See here. You could fix that by a dynamic memory allocation, something like:

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

And of course, don't forget to free the memory when finished.

Community
  • 1
  • 1
Neither_8
  • 111
  • 7
  • thank you for this, malloc and using pointers inside was a good solution to my crashes. – mr oh Jun 23 '15 at 03:02