Random array with many numbers getting error

2020-05-07 10:56发布

问题:

I have a homework to do: I need to measure the time for the bubblesort in a random array with 100000 numbers. I get an error when I try to randomly generate number.Also if I DON'T randomly generate numbers I get 0 everytime. I done this so far:

main.c 

int main()
{
    int *a,n = 0;
    srand(time(0));
    beolvas(&a,&n,"be.txt");
    clock_t start,stop;
    start = clock();
    bubblesort(a,n);
    stop = clock();
    float timespent = (stop - start)/CLOCKS_PER_SEC;
    printf("%f\n",timespent);

    kiir(a,n);
    free(a);
    return 0;
}

kibe.c(sorry I write it bad)

void beolvas(int **a,int *n,const char * file)
{
    int i;
    FILE * fin;
    fin = fopen("be.txt", "rt");
    *a = (int*)malloc(*n*sizeof(int));
    if(a == 0){printf("Error");return 0;}
    for(i = 0; i < 100000; ++i){
        *a = rand() % 100;
    }
    fclose(fin);
}
void bubblesort(int *a, int n)
{
    int i,j,csere;

    for(i = 0; i < n-1; ++i){
        for(j = 0; j < n - i -1; ++j){
            if (a[j] > a[j + 1]){
                csere = a[j];
                a[j] = a[j + 1];
                a[j + 1] = csere;
            }
        }
    }
}

void kiir(int *a,int n)
{
    int i;
    for(i = 0; i < n; ++i){
        printf("%i ",a[i]);
    }
}

As you see I need to use headers...It is really boring...

EDIT

Now I completely rewrite all program no errors no warnings, but it doesn't prints the array out and the sorting time is still 0.What I forgot to do ? And why my write function does nothing ?

sema.c

void read(int *a,int n)
{
    int i;
    scanf("%d",&n);
    a = (int*)malloc(n*sizeof(int));
    if(a == 0){printf("Error");return 0;}
    for(i = 0; i < n; ++i){
        a[i] = rand() % 100;
    }
}

void bubblesort(int *a,int n)
{
    int i,j,csere;

    for(i = 0; i < n-1; ++i){
        for(j = 0; j < n - i -1; ++j){
            if (a[j] > a[j + 1]){
                csere = a[j];
                a[j] = a[j + 1];
                a[j + 1] = csere;
            }
        }
    }
}
void write(int *a,int n)
{
    int i;
    for(i = 0; i < n; ++i){
        printf("%i ",a[i]);
    }
}

sema.h

void read(int*,int*);
void write(int*,int);
void bubblesort(int*,int);

main.c

int main()
{
    double *a = NULL ,n = 0;
    read(&a,&n);
    clock_t start,stop;
    start = clock();
    bubblesort(a,n);
    stop = clock();
    float elapsedTime = (stop - start)/CLOCKS_PER_SEC;
    printf("%f",elapsedTime);
    write(a,n);

    free(a);
    return 0;
}

回答1:

The line void beolvas(int **a,int *n,const char * file); is declaring a as a pointer to pointer.

But this line:

*a = rand() % 100;

is dereferencing it only once and assigning a value to a pointer (effectively causing a memory leak as it was malloc-ed before)

So you are getting various undefined behaviors.



回答2:

You should not use a int** var but simply a int*. Indeed, you only need to pass the adress of an int to your beolvas function. Then, don't forget to init you randomizer thanks to :

srand(time(NULL));  

Otherwise you will always generate the same "random" number. This is due to the fact that C compiler take time as a ref.

Don't forget that .h file in C should only contain headers of function. The function itself should be written in a .c file with the same name.

For the rest, your code look okay. Try to change your pointers and give us the errors if any.



回答3:

[..] no errors no warnings [..]

Which compiler are you using? I highly doubt that:

In main, you declare a pointer to double:

double *a = NULL;

You pass the address of that pointer (thus a pointer to that pointer, a double **) to your functions, but they expect an pointer to an integer:

void read(int*,int*);
void write(int*,int);
void bubblesort(int*,int);

The same goes for the second parameter, mostly called n in your functions: The function declarations assume a int, but you pass ...

double n = 0;
read(&a,&n);
// ...
bubblesort(a,n);
// ...
write(a,n);

... once a pointer to a double, and twice a double to your functions.

Generally, you seem to be confused about the concept of passing parameters, especially in combination with pointers. Remember: Every parameter you pass to a function in C gets copied. Thus:

void foo(int a) {
  a = 42;
  // a is now 42 for the rest of only this function
}
void bar(void) {
  int a = 21;
  foo(a);
  // a is still 21, this is not the a from foo.
}

Probably you should also read up upon lexical scoping, which is used in C (and most of current languages). Now consider passing a pointer:

static int fred = 42;
void foo(int * a) {
  // Dereferencing a gives us acces to whatever it points to
  *a = 42;
  // But modifying the variable a ...
  a = &fred;
  // a points to fred for the rest of only this function
}
void bar(void) {
  int john = 21;
  int * a = &john;
  foo(a);
  // a still points to john, this is not the a from foo.
  // but john is now 42!
}

Passing the pointer also only copies that pointer (think of it as an address). But using that pointer, you can access whatever it points to.

Getting back to your issue at hand, I think you should try to write the following functions (assuming you still want int numbers):

/** Allocate an array with random integers.

  This function takes as parameter the count of elements the
  array is supposed to have. A pointer to the array filled with random
  integers should be returned.
*/
int * allocate_random_integers(size_t count);


/** Sort the array.

  This function is supposed to sort the given array (a pointer to its
  first element is given along with the number of elements).
*/
void bubblesort(int * array, size_t count);

/** Print the array to stdout.

  This function is supposed to write each element of the given array to
  stdout.
*/
void print(int const * array, size_t count);

A few things to note:

  • I use size_t for anything that's "sizey" (including indices).
  • Instead of returning a pointer from allocate_random_integers one could also pass a pointer to a pointer and set that pointer pointed to it to the pointer to the array (void allocate_random_integers(int ** array_ptr, size_t count)).
  • print takes a int const * instead of an int * to make it obvious to the caller (and the type system) that the array isn't modified during printing.
  • Don't forget to free the array once done.


标签: c random header