views:

1007

answers:

6

Hello to all,

The following C Code gives a segmentation fault:

#include <stdio.h>
#include <stdint.h>

int main(){
        uint32_t *a;
        uint32_t idx=1233245613;
        a[idx]=1233;
        return 0;
}

How can I use uint32_t as index of an array in C? Or how can I use array like structure which can get uint32_t and 12 digit numbers as an index?

I'd appreciate any kind of help.

+6  A: 
  • The variable "a" is just a pointer varaible.
  • A pointer variable holds the address of a memory location.
  • You need to point a to a memory location that has the space you need already allocated.

Also you are trying to index pretty far in the array. You may not have enough memory available for this so be sure to check for NULL.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main(void){

        uint32_t *a;
        uint32_t idx=1233245613;

        //This allows you to index from 0 to 1233245613
        // don't try to index past that number
        a = malloc((idx+1) * sizeof *a);
        if(a == NULL)
        {
           printf("not enough memory");
           return 1;
        }


        a[idx]=1233;
        free(a);
        return 0;
}
Brian R. Bondy
Thanx Brian adding #include <stdlib.h> solved my problem. I haven't been using c for a long time so I forget the basics in today's garbage collection world :D.
systemsfault
Thanks, I added this header to my answer.
Brian R. Bondy
thx for the fixes unwind
Brian R. Bondy
Things are a bit different in C++. First, use std::vector<>, not arrays. Second, if you have to use arrays, consider new[]. Third, if you do use malloc(), you'll have to cast the result. This is excellent C, but won't compile in C++.
David Thornley
I think not being able to hold 1.2 billion elements is going to be a "basic" in almost any language.
T.E.D.
+2  A: 

Well for starters you need to allocate space to a.

When that code runs, a points to some space in memory that you probably don't own.
When you try to access it (actually when you try to access a + 1233245613) you're going to some space in memory you definetly don't own, and that is a no-no and will cause a crash.

#include <stdio.h>
#include <stdint.h>

int main(){
        uint32_t *a;
        uint32_t idx=1233245613;
        a = malloc(sizeof(unit32_t) * (idx+1));//+1 cause remember, arrays are 0-based
        if(a == NULL) 
        {
           printf("Array could not be allocated"); 
           return 1;
        }
        a[idx]=1233;
        free(a);//good practice to avoid memory leaks
        return 0;
}

But even that doesn't solve the problem that you're using a GIANT array. Your standard setup (desktop or even most servers) will choke trying to allocate 4.6GB of memory. So unless you've taken that into account you're probably going to need to step back and rethink what you're trying to do, and how.

Tom Ritter
it's tagged as C, not C++.
Ferruccio
You might want to check success using "if (a != NULL)", because this tries to allocate around 4,9 GB memory.
schnaader
Ah C. It's been so long. I've edited about 7 times so far....
Tom Ritter
Thanx for your comment Tom
systemsfault
A: 

a is a pointer which points to nothing determinate. You want an array

uint32_t a[42];

which creates an array of 42 integers. However, your access to it will still cause problems (undefined behaviour to be exact) as it is way outside the bounds of this or any other sensible array.

anon
+5  A: 

If you want to use a "12-digit number" as the index, that implies that you want need more than 1 billion items. With each item being an uint32_t, that implies that each takes four bytes of memory. Therefore, you're looking at around 4 GB in memory total for this array. Arrays are not usually made that big, for performance and other reasons.

If you really need each of those billion items, look into disk-backed algorithms, perhaps Red-Black Trees, that are suitable for implementing this kind of giant array.

unwind
The amount of rotations needed to add new items to a Red-Black tree that size would be insane, so surely that's a terrible solution?
Ed Woodcock
Programming Pearls Chapter 1 :D
systemsfault
additionally, regardless of how you're storing it (unless it's sparse array, but then why use an array-like structure at all), you're going to hit the memory limit for a 32 bit process. You'll need a 64 bit OS and compiler.
rmeador
+1  A: 

You need two things:

  • allocate memory for the a array, something like uint32_t a[2000000000];
  • compile on a 64 bit architecture which can address more than 4Gb of memory.
mouviciel
+1  A: 

Whoa. That's messed up.

OK. Two problems here. The first problem is that you declared a pointer to integer, never pointed it to anything, and then tried to use it. This is just flat out a bug. Most likely, the pointer happens to point to a place that isn't even valid memory for your process (or to NULL). In that case, any attempt to use it will give you a segfault, just like you got.

The second problem is the value you are trying to index it by. Even if you had allocated memory for your pointer, I seriously doubt you could have allocated 4.8 Gigabytes for it. Most computers don't have anywhere near that much RAM, and certianly don't have that much in one contiguous chunk. If you try to index past the memory you have allocated to an array, darn near anything could happen, but if you go way past, most likely you will get a segfault.

T.E.D.