silent error on array of structs allocation [duplicate] - arrays

you guys have helped me so much with this code. Let me preface by saying I do not know C very well and am trying really hard to do this.
This is what the program should do:
Create a list of random numbers of length 10 Million
Sort the list of random numbers using shell sort function (still doesn't work properly...i think its how I am passing the pointer to the function)
Make a list 1 Million Longer
repeat for up to 100 million while recording time (the time shows up as 0.0000000 for some reason)
I'm just trying to test this shell sort program vs quick sort built into the standard library.
I've tried with and without pointers. The commented out section should work when it's done. It just messes things up more lol
Please help me out, you guys have been so great so far...
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shellSort(int *A, int n);
void checkSort(int *A, int n);
int main(){
/*Initialize Random Array*/
int unsorted_list[10000000];
int *ptr = &unsorted_list[0];
int random_number;
int i;
srand ( time(NULL) );
for(i=0; i<10000000; i++){
random_number = rand();
unsorted_list[i] = random_number % 10000000;
}
//Do C Shell Sort
double shell_results[10][2];
double clock_diff;
int j=10000000;
clock_t t0, t1;
int k;
for(i=0;i<10;i++){
/*Sort the list using shellSort and take the time difference*/
t0 = clock();
shellSort(ptr, j);
t1= clock();
/*Take difference in time*/
clock_diff = (t1 - t0)/CLOCKS_PER_SEC;
/*Add time and list length to the results array*/
shell_results[i][0] = (double)j;
shell_results[i][1] = clock_diff;
/*Check to make sure the array has been sorted*/
checkSort(ptr, j);
/*Re-initialize a longer array*/
//j+=1000000;
//for(k=0; k<j; k++){
// random_number = rand();
// unsorted_list[k] = random_number % 1000000;
//}
printf("%d",(int)shell_results[i][0]);
printf(" ");
printf("%f",shell_results[i][1]);
printf("\n");
}
return 0;
}
void shellSort(int *A, int n){
int gap , i , j , temp;
for (gap = n/2; gap>0; gap /=2)
for (i=gap; i<n; i++)
for(j = i-gap; j>=0 && A[j] > A[j+gap]; j-=gap){
temp = A[j];
A[j] = A[j + gap];
A[j + gap] = temp;
}
}
void checkSort(int *A, int n){
int i;
for(i=0;i<n;i++){
if(A[i]>A[i+1]){
printf("Error in sorting \n");
break;
}
}
}

You probably don't have 10 megabytes of stack space. Make that array global, declare it with static, or allocate it dynamically using malloc(). If you choose the latter, don't forget to free() it.
Later, when you need to use the 100,000,000 element array, make sure to use a new allocation for it!

Well there is no way you are going to have that amount of space available on the stack. Allocate it off the heap using malloc(). Remember to free() it afterwards.

Related

Changing the value of a variable with pointers not working

Basically I have a function called MinSubTab that is supposed to calculate the sum of the array passed and also to change the value passed in the first argument from inside the function without using return. This is done with pointers. Anyway, I think it'd be easier if I just showed you the code so here it is:
maintab.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tab.h"
int main(){
int *reftab;
int min;
reftab = (int *)malloc(sizeof(int) * NMAX);
InitTab(reftab,NMAX);
printf("\n Total: %d et min: %d", MinSumTab(&min, reftab, NMAX), min);
free(reftab);
return 0;
}
tab.c
void InitTab(int *tab, int size){
srand(time(NULL));
for (int i=0; i<size; i++){
*(tab+i) = rand() % 10;
}
}
int MinSumTab(int *min, int *tab, int size){
int total=0;
int minimum = NMAX;
int temp = *min;
for (int i=0; i<size; i++){
total += *(tab+i);
}
for (int i=0; i<size; i++){
if(*(tab+i)<minimum){
minimum = *(tab+i);
}
}
*min = minimum;
return total;
}
So the expected result here is that the sum is printed (which it is) and the minimum value of the array is printed (which it is not). Every single time the min variable equals 8 and I've no idea how to actually change the value of min from within that function.
Please help as my brain has no more capacity for rational thought, it's been 1.5 hrs and no solution in sight. Thanks
Looks like a small mistake:
You initialize minimum with NMAX, which I assume is 8 (the size of the array). 99.9% of the random numbers will be bigger. So 8 is chosen as the minimum.
What you really want is to initialize it with RAND_MAX – the maximum value rand() can return.
In C order of evaluation and argument passing is undefined.
You can of course the order yourself but it only to feed your curiosity.
#include <stdio.h>
volatile char *message[] = {
"fisrt", "second", "third", "fourth"
};
int print(size_t x)
{
printf("%s\n", message[x]);
return x;
}
int main()
{
printf("%d %d %d %d\n", print(0), print(1), print(2), print(3));
return 0;
}
Note. There is one exception from this rule.
Logical operators are evaluated form the left to the right.
if( x != NULL && *x == 5)is safe because x will not be dereferenced if it is NULL

C Program crashes(Segmentation Fault) for large size of input array. How to prevent it without using static/global/malloc?

The following program is to sort a large array of random numbers using heapsort. The output of the program is the total execution time of the recursive heapSort function(in microseconds). The size of the input array is defined by the SIZE macro.
The program works fine for SIZE up to 1 million(1000000). But when I try to execute the program with SIZE 10 million(10000000), the program generates segmentation fault(core dumped).
Note: I have already tried increasing the soft and hard limits of the stack using ulimit -s command on Linux(128 MB). The SEGFAULT still persists.
Please suggest me any alterations to the code needed or any method which will overcome the existing SEGFAULT malady without having to declare the array dynamically or as global/static.
/* Program to implement Heap-Sort algorithm */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
long SIZE = 10000000; // Or #define SIZE 10000000
long heapSize;
void swap(long *p, long *q)
{
long temp = *p;
*p = *q;
*q = temp;
}
void heapify(long A[], long i)
{
long left, right, index_of_max;
left = 2*i + 1;
right = 2*i + 2;
if(left<heapSize && A[left]>A[i])
index_of_max = left;
else
index_of_max = i;
if(right<heapSize && A[right]>A[index_of_max])
index_of_max = right;
if(index_of_max != i)
{
swap(&A[index_of_max], &A[i]);
heapify(A, index_of_max);
}
}
void buildHeap(long A[])
{
long i;
for(i=SIZE/2; i>=0 ; i--)
heapify(A,i);
}
void heapSort(long A[])
{
long i;
buildHeap(A);
for(i=SIZE-1 ; i>=1 ; i--)
{
swap(&A[i], &A[0]);
heapSize--;
heapify(A, 0);
}
}
int main()
{
long i, A[SIZE];
heapSize = SIZE;
struct timespec start, end;
srand(time(NULL));
for(i = 0; i < SIZE; i++)
A[i] = rand() % SIZE;
/*printf("Unsorted Array is:-\n");
for(i = 0; i < SIZE; i++)
printf("%li\n", A[i]);
*/
clock_gettime(CLOCK_MONOTONIC_RAW, &start);//start timer
heapSort(A);
clock_gettime(CLOCK_MONOTONIC_RAW, &end);//end timer
//To find time taken by heapsort by calculating difference between start and stop time.
unsigned long delta_us = (end.tv_sec - start.tv_sec) * 1000000 \
+ (end.tv_nsec - start.tv_nsec) / 1000;
/*printf("Sorted Array is:-\n");
for(i = 0; i < SIZE; i++)
printf("%li\n", A[i]);
*/
printf("Heapsort took %lu microseconds for sorting of %li elements\n",delta_us, SIZE);
return 0;
}
So, once you plan to stick with stack-only approach, you have to understand who is the main consumer(s) of your stack space.
Player #1: Array A[] itself. Depending to the OS/build, it consumes approx. 40 or 80 Mb of stack. One-time only.
Player #2: Beware recursion! In your case, this is heapify() function. Each call consumes decent stack chunk to serve a calling convention, stack alignment like stack-frames etc. If you do that million times and tree-like schema, you have tens of megabytes spent here too. So, you can try to re-implement this function to non-recursive way to decrease stack size pressure.

Freeing a 2-D array in C

Please bear with me as this is probably a very simple question but I am very new to C.
I am trying to malloc a specific array and then free it. However, the line:
M = malloc(N*sizeof(double *));
...doesn't work. Can somebody please explain to me why this is not working and what the solution would be? Many thanks in advance.
You should free all positions, not just the first. See this example I have wrote.
As mentioned from #Grijesh, the allocation is also wrong. The example covers allocation too. Moreover, I suggest you not to cast the return of malloc (more).
You have to think the 2D array, as a 1D array, where every cell of it is a pointer to a 1D array. A picture might help:
http://gsamaras.files.wordpress.com/2014/04/array2d-n.png
Here, 1D array that holds the pointers is to the left and every cell of it, points to another 1D array.
How many 1D arrays to the left? As many cells as you have in the left array.
Btw, Nelly I think this is not a silly question, it's something that gets beginners into trouble. ;)
EDIT:
About your new code, you had to have the same definition and declaration for matrix_free, as well as, call it as you should. What's definition, etc. ?? Answer.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define Nmax 9000
double **makeMatrix(int N);
void free_matrix(double **M,int N);
int main(void) {
int N;
for (N = 2; N < Nmax; N *= 2) {
double **L = makeMatrix(N);
printf("yes \n");
free_matrix(L, N);
printf("woo \n");
}
return 0;
}
double **makeMatrix(int N) {
int i, j;
double **M;
M = malloc(N * sizeof(double *));
for (i = 0; i < N; i++)
M[i] = malloc(N * sizeof(double));
for (i = 1; i < N; i++) {
for (j = 1; j < N; j++) {
M[i][j] = (i) * (j) * M_PI / N;
}
}
return (M);
}
void free_matrix(double **M, int N) {
int i;
for (i = 1; i <= N; i++) {
free(M[i]);
}
free(M);
}
And then I receive the youwho output. :) But, it will stop at a certain point, because NMAX is too big! Not only NMAX is too big, but N grows really fast ( N *=). Have you done the math in a piece of paper? Too big numbers. For example, if I do N +=, then, I can go until NMAX = 9000.
Debug tip:
How do I know in which loop it reaches?
I printed out the counter of the loop, like this
printf("woo %d\n",N);
Of course, if you feel sure for yourself, then I suggest you learning the debugger.

How do I tell a C program to create n arrays, reading n by scanf?

I'd like to create a small program that adds, subtracts, multiplies and does a cross product for vectors.
Therefore I'd like to have the user enter
- the amount of vectors
- the dimension of said vectors
- what exactly he wants to do with the vectors (one of the above mentioned functions)
Since I am quite new to programming maybe I haven't found the correct source yet, in this case I would be grateful for a hint in the right direction (especially what to search exactly, since I am not a native speaker)
My problem:
I don't know how to program the sum function so that it always sums up n vectors (n being the amount of vectors the user entered)
I have a rough idea about the rest of the functions so maybe I won't bother you with this program again but this sum-problem really is a problem for me.
I'm sure the answer is somewhere near but I just don't seem to be able to find it.
So many thanks in advance :)
Simple vector
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Type;
typedef struct vector {
size_t size;
size_t capacity;
Type *array;
} Vector;
Vector *vec_make(){
Vector *v;
v = (Vector*)malloc(sizeof(Vector));
v->size = 0;
v->capacity=16;
v->array=(Type*)realloc(NULL, sizeof(Type)*(v->capacity += 16));
return v;
}
void vec_pushback(Vector *v, Type value){
v->array[v->size] = value;
if(++v->size == v->capacity)
v->array=(Type*)realloc(v->array, sizeof(Type)*(v->capacity += 16));
}
size_t vec_size(Vector *v){
return v->size;
}
Type *vec_getArray(Vector *v){
return v->array;
}
void vec_free(Vector *v){
free(v->array);
free(v);
}
int main(){
int n=5;//user input
Vector *a, *b, *c;
int i, sum=0, size;
int *ap, *bp, *cp;
a = vec_make(); b = vec_make(); c = vec_make();
for (i=0; i<n; ++i) {
vec_pushback(a, i+1);//1,2,3,4,5
}
vec_pushback(b, 2);
vec_pushback(b, 4);
vec_pushback(b, 5);
vec_pushback(b, 6);
vec_pushback(b, 10);
ap=vec_getArray(a);bp=vec_getArray(b);cp=vec_getArray(c);
for(i=0;i<a->size;++i){
sum+=ap[i];
}
printf("sum(va)=%d\n", sum);
size=vec_size(b);
for(i=0;i<size;++i)
vec_pushback(c, ap[i]+bp[i]);
printf("va + vb = vc(");
for(i=0;i<size;++i){
printf("%d", cp[i]);
if(i<size-1)
printf(",");
else
printf(")\n");
}
vec_free(a);vec_free(b);vec_free(c);
return 0;
}
Are you using straight C or C++?
Since you want dynamic memory allocation, I'd really recommend C++ since you can use std::vector for your array which is totally straightforward. The C way is not nearly as simple.
http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm
This question explains how to malloc a 2-d array Using malloc for allocation of multi-dimensional arrays with different row lengths basically you start by allocating an array of n int pointers then you loop over that array and do array[i] = (int*)malloc(sizeof(int) * lenght))
Putting that into more a step by step how to;
1) allocate an array of int pointers - int** array = malloc(sizeof(int*) * n);
you use ** because your first pointer points the the beginning of the array and the array is of type int*, each of these int pointers will point to another array.
2) loop over the array - for (i = 0; i < n; i++)
in C there is no simple way to malloc 2-d arrays. you have to build each row 1 by 1.
3) inside the loop allocate the horizontal array - array[i] = (int*)malloc(sizeof(int) * length)
The question I link to includes some checks to make sure the allocation was successful. I don't know how necessary this is, but it can't hurt.

Segmentation Fault While Creating Large Arrays in C

you guys have helped me so much with this code. Let me preface by saying I do not know C very well and am trying really hard to do this.
This is what the program should do:
Create a list of random numbers of length 10 Million
Sort the list of random numbers using shell sort function (still doesn't work properly...i think its how I am passing the pointer to the function)
Make a list 1 Million Longer
repeat for up to 100 million while recording time (the time shows up as 0.0000000 for some reason)
I'm just trying to test this shell sort program vs quick sort built into the standard library.
I've tried with and without pointers. The commented out section should work when it's done. It just messes things up more lol
Please help me out, you guys have been so great so far...
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shellSort(int *A, int n);
void checkSort(int *A, int n);
int main(){
/*Initialize Random Array*/
int unsorted_list[10000000];
int *ptr = &unsorted_list[0];
int random_number;
int i;
srand ( time(NULL) );
for(i=0; i<10000000; i++){
random_number = rand();
unsorted_list[i] = random_number % 10000000;
}
//Do C Shell Sort
double shell_results[10][2];
double clock_diff;
int j=10000000;
clock_t t0, t1;
int k;
for(i=0;i<10;i++){
/*Sort the list using shellSort and take the time difference*/
t0 = clock();
shellSort(ptr, j);
t1= clock();
/*Take difference in time*/
clock_diff = (t1 - t0)/CLOCKS_PER_SEC;
/*Add time and list length to the results array*/
shell_results[i][0] = (double)j;
shell_results[i][1] = clock_diff;
/*Check to make sure the array has been sorted*/
checkSort(ptr, j);
/*Re-initialize a longer array*/
//j+=1000000;
//for(k=0; k<j; k++){
// random_number = rand();
// unsorted_list[k] = random_number % 1000000;
//}
printf("%d",(int)shell_results[i][0]);
printf(" ");
printf("%f",shell_results[i][1]);
printf("\n");
}
return 0;
}
void shellSort(int *A, int n){
int gap , i , j , temp;
for (gap = n/2; gap>0; gap /=2)
for (i=gap; i<n; i++)
for(j = i-gap; j>=0 && A[j] > A[j+gap]; j-=gap){
temp = A[j];
A[j] = A[j + gap];
A[j + gap] = temp;
}
}
void checkSort(int *A, int n){
int i;
for(i=0;i<n;i++){
if(A[i]>A[i+1]){
printf("Error in sorting \n");
break;
}
}
}
You probably don't have 10 megabytes of stack space. Make that array global, declare it with static, or allocate it dynamically using malloc(). If you choose the latter, don't forget to free() it.
Later, when you need to use the 100,000,000 element array, make sure to use a new allocation for it!
Well there is no way you are going to have that amount of space available on the stack. Allocate it off the heap using malloc(). Remember to free() it afterwards.

Resources