How to find the problems of reallocation when it is not done - c

Consider the following code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX_NUM 5
#define MAX_INCR 5
int main(void)
{
char check = 'y';
int max_number = MAX_NUM;
double *array_input = NULL;
int i = 0;
double buffer = 0.0;
int count = 0;
array_input = malloc(5 * (sizeof(double)));
printf("Please enter the numbers into the array: ");
for(i = 0; i < max_number; i++)
{
++count;
scanf("%lf", &buffer);
*(array_input + i) = buffer;
if(count == max_number)
{
printf("\nDo you want to input more?(y/n) ");
fflush(stdin);
if((check = tolower(getchar())) == 'y')
{
max_number += MAX_INCR;
//realloc(array_input, max_number);
continue;
}
}
}
for(int j = 0; j < max_number; j++)
{
printf("\nThe value is: %lf", *(array_input + j));
}
return 0;
}
(freeing the memory is not done to keep the code consise)
Now, the reallocation is not done in here deliberately but the output of the program is exactly what it should be.
e.g. 5.3, 4.2, 5.6. 7.4, 3, 2, 4, 5, 6, 7.8, the program outputs these numbers as it is, like it should.
How to figure out that there's a possible error in this program?(Example: Someone is given the program but the programmer forgot the reallocation part, it may later cause problems, right?)

The problem with "undefined behaviour" is that you never know. In many cases, just like yours, the program apparently behaves normal, but once you change a little bit, it suddenly crashes, even though the change itself is done correctly. Such bugs often cause security holes, since hackers can exploit them to run their own code.
There are tools to find bugs like that, e.g. http://valgrind.org/

You will never know until exception occurs. That is why people do implement various of testing codes including unit testing and function testing, etc...
Those testings enhance its reliability and quality.
Codes which has security holes are the same.
Programmers who coded could believe that the programmed code is very solid. For example, like the developers who developed remote-drive using network connection secured. However, hackers study the weakness and try many attempts to find the weakness of the system and finally it breaks. After coder finds out its weakness, programmers improve their code from the defect. This is why cyber attack is called spear (who try to attack) and shield (who try to defense).
There are no perfect code. Once it finds its bug, it is needed to improve its quality.

Related

Why does my code run when i debugg but when i press build & run it crashes?

So we got an assignment in uni to format a text.
The max width of a line shoud be 68 characters and if the words dont fill the line we have to fill the empty spaces with blanks, equally distributed between far left and far right.
The Problem is when i build and run the programm it crashes but when im debugging it, it runs fine.
My Compiler is Codeblocks 17.12 and to debugg im using minGW gdb.
Im pretty new to programming and know that my code is probalby not the greatest.
We got the function readtext from our professor.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define WORDS_LIMIT 10000
//------------------------------------------------------------
int readtext(const char* filename, int *maxWidth, char *words[], const int WordsLimit){
int WordCount=0;
FILE* Infile;
Infile=fopen(filename, "r");
assert(Infile);
fscanf(Infile, "%i\n", maxWidth);
char line[BUFSIZ];
while (fgets(line, BUFSIZ, Infile) && WordsLimit>WordCount)
{
// remove newline
char *newline = strchr(line, '\n');
if (newline) {
*newline = '\0';
}
words[WordCount++]=strdup(line);
}
return WordCount-1;
}
//------------------------------------------------------------
int letterCount (char *Zeile[], int wordCount){
int wordWidth = 0;
int i = 0;
while (i <= wordCount){
if (strlen(Zeile[i]) > 0 && strlen(Zeile[i]) < 68 ){
wordWidth = wordWidth + strlen(Zeile[i]);
i++;
}else{
i++;
break;
}
}
return wordWidth;
}
//------------------------------------------------------------
int findWords(char *Zeile[], char *words[]){
int Width = 0;
int k = 0;
int wordsPerLine = 0;
while (Width <= 68 && strlen(words[k]) > 0) {
Width = strlen(words[k]) + 1;
Zeile[k] = words[k];
wordsPerLine = wordsPerLine+1;
k++;
}
return wordsPerLine;
}
//------------------------------------------------------------
int formatBlanksLine (int lettersPerLine, int wordCount){
int BlanksPerLine = 0;
BlanksPerLine = 68 - (lettersPerLine + wordCount);
return BlanksPerLine;
}
//------------------------------------------------------------
int formatBlanksRight(int BlanksLine, int BlanksRight){
if (BlanksLine % 2 == 0){
BlanksRight = (BlanksLine / 2) - 1;
}
else{
BlanksRight = (BlanksLine / 2) - 2;
}
return BlanksRight;
}
//------------------------------------------------------------
int formatBlanksLeft(int BlanksLine, int BlanksLeft){
if (BlanksLine % 2 == 0){
BlanksLeft = (BlanksLine / 2);
}
else{
BlanksLeft = (BlanksLine / 2) + 1;
}
return BlanksLeft;
}
//------------------------------------------------------------
int main(int argc, char *argv[]){
char *Zeile[68];
char *filename = "Cathedral_1.txt";
char *words[WORDS_LIMIT];
int wordCount = 0;
int NumWords = 0;
int maxWidth;
int lettersPerLine = 0;
int BlanksLine = 0;
int BlanksLeft = 0;
int BlanksRight = 0;
//------------------------------------------------------------
// use filename from commandline
if (argc > 1) {
filename = argv[1];
}
// overwrite textwidth with the 2nd argument from the commandline
if (argc > 2) {
maxWidth = atoi(argv[2]);
}
//------------------------------------------------------------
NumWords = readtext(filename, &maxWidth, words, WORDS_LIMIT);
wordCount = findWords(Zeile, words);
lettersPerLine = letterCount(Zeile, wordCount);
BlanksLine = formatBlanksLine(lettersPerLine, wordCount);
BlanksLeft = formatBlanksLeft(BlanksLine, BlanksLeft);
BlanksRight = formatBlanksRight(BlanksLine, BlanksRight);
//------------------------------------------------------------
printf("Format text to %d chars per line\n", maxWidth);
for (int i=0; i < NumWords; i++)
{
printf("%s\n", words[i]);
}
//------------------------------------------------------------
printf("-----------------------------------\n");
for (int i = 0; i < BlanksLeft; i++){
printf("0");
}
for (int i=0; i < wordCount ; i++)
{
printf("%s0", Zeile[i]);
}
for (int i = 0; i < BlanksRight; i++){
printf("0");
}
//------------------------------------------------------------
printf("\n-----------------------------------\n");
printf("Die Anzahl der Buchstaben ist: %d\n", lettersPerLine);
printf("-----------------------------------\n");
//------------------------------------------------------------
return 0;
}
Cathedral.txt
The Cathedral and the Bazaar
Linux is subversive. Who would have thought even five years ago (1991) that a world-class operating system could coalesce as if by magic out of part-time hacking by several thousand developers scattered all over the planet, connected only by the tenuous strands of the Internet?
Certainly not I. By the time Linux swam onto my radar screen in early 1993, I had already been involved in Unix and open-source development for ten years. I was one of the first GNU contributors in the mid-1980s. I had released a good deal of open-source software onto the net, developing or co-developing several programs (nethack, Emacs's VC and GUD modes, xlife, and others) that are still in wide use today. I thought I knew how it was done.
Linux overturned much of what I thought I knew. I had been preaching the Unix gospel of small tools, rapid prototyping and evolutionary programming for years. But I also believed there was a certain critical complexity above which a more centralized, a priori approach was required. I believed that the most important software (operating systems and really large tools like the Emacs programming editor) needed to be built like cathedrals, carefully crafted by individual wizards or small bands of mages working in splendid isolation, with no beta to be released before its time.
Linus Torvalds's style of development-release early and often, delegate everything you can, be open to the point of promiscuity-came as a surprise. No quiet, reverent cathedral-building here-rather, the Linux community seemed to resemble a great babbling bazaar of differing agendas and approaches (aptly symbolized by the Linux archive sites, who'd take submissions from anyone) out of which a coherent and stable system could seemingly emerge only by a succession of miracles.
The fact that this bazaar style seemed to work, and work well, came as a distinct shock. As I learned my way around, I worked hard not just at individual projects, but also at trying to understand why the Linux world not only didn't fly apart in confusion but seemed to go from strength to strength at a speed barely imaginable to cathedral-builders.
By mid-1996 I thought I was beginning to understand. Chance handed me a perfect way to test my theory, in the form of an open-source project that I could consciously try to run in the bazaar style. So I did-and it was a significant success.
This is the story of that project. I'll use it to propose some aphorisms about effective open-source development. Not all of these are things I first learned in the Linux world, but we'll see how the Linux world gives them particular point. If I'm correct, they'll help you understand exactly what it is that makes the Linux community such a fountain of good software-and, perhaps, they will help you become more productive yourself.
Cathedral_1.txt
68
The
Cathedral
and
the
Bazaar
Linux
is
subversive.
Who
would
have
thought
even
five
years
ago
(1991)
that
a
world-class
operating
system
could
coalesce
as
if
by
magic
out
of
part-time
hacking
by
several
thousand
developers
scattered
all
over
the
planet,
connected
only
by
the
tenuous
strands
of
the
Internet?
Certainly
not
I.
By
the
time
Linux
swam
onto
my
radar
screen
in
early
1993,
I
had
already
been
involved
in
Unix
and
open-source
development
for
ten
years.
I
was
one
of
the
first
GNU
contributors
in
the
mid-1980s.
I
had
released
a
good
deal
of
open-source
software
onto
the
net,
developing
or
co-developing
several
programs
(nethack,
Emacs's
VC
and
GUD
modes,
xlife,
and
others)
that
are
still
in
wide
use
today.
I
thought
I
knew
how
it
was
done.
Linux
overturned
much
of
what
I
thought
I
knew.
I
had
been
preaching
the
Unix
gospel
of
small
tools,
rapid
prototyping
and
evolutionary
programming
for
years.
But
I
also
believed
there
was
a
certain
critical
complexity
above
which
a
more
centralized,
a
priori
approach
was
required.
I
believed
that
the
most
important
software
(operating
systems
and
really
large
tools
like
the
Emacs
programming
editor)
needed
to
be
built
like
cathedrals,
carefully
crafted
by
individual
wizards
or
small
bands
of
mages
working
in
splendid
isolation,
with
no
beta
to
be
released
before
its
time.
Linus
Torvalds's
style
of
development-release
early
and
often,
delegate
everything
you
can,
be
open
to
the
point
of
promiscuity-came
as
a
surprise.
No
quiet,
reverent
cathedral-building
here-rather,
the
Linux
community
seemed
to
resemble
a
great
babbling
bazaar
of
differing
agendas
and
approaches
(aptly
symbolized
by
the
Linux
archive
sites,
who'd
take
submissions
from
anyone)
out
of
which
a
coherent
and
stable
system
could
seemingly
emerge
only
by
a
succession
of
miracles.
The
fact
that
this
bazaar
style
seemed
to
work,
and
work
well,
came
as
a
distinct
shock.
As
I
learned
my
way
around,
I
worked
hard
not
just
at
individual
projects,
but
also
at
trying
to
understand
why
the
Linux
world
not
only
didn't
fly
apart
in
confusion
but
seemed
to
go
from
strength
to
strength
at
a
speed
barely
imaginable
to
cathedral-builders.
By
mid-1996
I
thought
I
was
beginning
to
understand.
Chance
handed
me
a
perfect
way
to
test
my
theory,
in
the
form
of
an
open-source
project
that
I
could
consciously
try
to
run
in
the
bazaar
style.
So
I
did-and
it
was
a
significant
success.
This
is
the
story
of
that
project.
I'll
use
it
to
propose
some
aphorisms
about
effective
open-source
development.
Not
all
of
these
are
things
I
first
learned
in
the
Linux
world,
but
we'll
see
how
the
Linux
world
gives
them
particular
point.
If
I'm
correct,
they'll
help
you
understand
exactly
what
it
is
that
makes
the
Linux
community
such
a
fountain
of
good
software-and,
perhaps,
they
will
help
you
become
more
productive
yourself.
This is prefaced by my top comments.
Okay ...
In letterCount, you have:
while (i <= wordCount)
This goes one beyond the end of the array. What you want is:
while (i < wordCount)
The first version would segfault because Zeile is an array of char pointers and we'd hit an uninitialized pointer.
This is UB. So, it tried to dereference whatever came after. Under debug, it still got a wrong value, but, somehow, that value was "harmless" (e.g. did not segfault).
As I mentioned in my top comments, we still want to change:
char *Zeile[68];
Into:
char *Zeile[WORDS_LIMIT];

Monty Hall Problem C Monte Carlo Simulation

So after seeing another video for the Monty Hall Problem and since I learned about Monte Carlo simulation methods, I thought I would try to find the percentage 66,66% of winning the game if you switch doors. The problem is that I get 50%, and one thing that worried when thinking up the algorithm is if my model was correct. I had 2 random guesses implemented, one for choosing door 1 to 3 with 1 in 3 chances and one for choosing to switch doors with 1 in 2 chances. The if statements were for assigning the doors with the prizes and for the different possibilities for each of those guesses. I don't know if I can reduce that part, but it works for now (I think). Where was my thinking incorrect? And can you suggest a fix to my algorithm? Thank you very much!
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int seed=time(NULL);
srand(seed);
double u, random[2], suitch=0.0, total=0.0;
int nall=10000000, nright=0, i, door[3], k, j;
for(j=0; j<nall; j++)
{
for(i=0; i<3; i++)
random[i]=0.0, door[i]=0;
for(i=0; i<2; i++)
{
u=(1.*rand())/RAND_MAX;
random[i]=3.*u;
//printf("%lf\t%lf\n",u,random[i]);
}
suitch=2.*u;
//printf("%lf\n",suitch);
if(floor(random[0])==0)
door[0]=1, door[1]=0, door[2]=0;
else if(floor(random[0])==1)
door[0]=0, door[1]=1, door[2]=0;
else if(floor(random[0])==2)
door[0]=0, door[1]=0, door[2]=1;
for(i=0; i<3; i++)
//printf("%d\t",door[i]);
if((floor(random[1])==0)&&(floor(suitch)==0))
k=door[0];
else if((floor(random[1])==1)&&(floor(suitch)==0))
k=door[1];
else if((floor(random[1])==2)&&(floor(suitch)==0))
k=door[2];
else if((floor(random[1])==0)&&(floor(suitch)==1))
{
if(door[1]==1)
k=door[1];
else if(door[1]==0)
k=door[2];
}
else if((floor(random[1])==1)&&(floor(suitch)==1))
{
if(door[0]==1)
k=door[0];
else if(door[0]==0)
k=door[2];
}
else if((floor(random[1])==2)&&(floor(suitch)==1))
{
if(door[0]==1)
k=door[0];
else if(door[0]==0)
k=door[1];
}
if(k==1)
nright++;
}
total=1.*nright/nall;
printf("%d\t%d\t%lf\t", k, nright, total);
return 0;
}
I've been looking at your code way too long, unable to see the problem. What an idiot i've been, lol. There is no problem with the code (except for an accidental, and luckily benign, memory overrun). The problem is what are you trying to simulate.
You simulate 10000000 games, where in half of the cases the player decides to keep his door (his chance is 33.3% in this case) and half of the cases where the player decides to switch (his chance is 66.7% in this case). Of course you are getting 50%, cause thats what you are simulating.
Set suitch = 1, permanently, and you'll... get 66.7%
And yea... please make random 3 elements long or stop initing at the beginning to fix the memory overrun, and comment out the former debug for(i=0; i<3; i++), cause you are running the simulation ifs chain 3 times each iteration for no good reason. But thats unrelated :-)

Im having problems using stdin and NULL in eclipse

Here is my code that I am having issues with. The goal of the program is to scan in a bunch of doubles and perform some simple statistical operations on them. The line I am having the issue with is the fgets(). I have included the stdio.h, it's just not showing up in the code. My actual question is where are the stdin and NULL giving me issues when I though they were part of the language? The exact error I am getting is that both Symbol stdin and NULL could not be resolved.
/*
* simpleStats.c
*
* Created on: Sep 17, 2018
* Author: David Liotta
*/
#include <stdio.h>
#define BUFSIZE 256
int main(){
double n, max, min, sum, mean;
char line[BUFSIZE];
int numsRead = 0;
int numOfItems = 1;
n = -1;
max = n;
min = n;
sum = n;
while(n != 0 && fgets(line, BUFSIZE, stdin ) != NULL){
numsRead = sscanf(line, "%f", &n);
if(numsRead == 1 && n != 0){
numOfItems++;
if(n > max)
max = n;
if(n < min)
min = n;
sum = sum + n;
}
if(numsRead == 0)
printf("Bad input\n");
}
mean = sum / numOfItems;
printf("# of items: %i", numOfItems);
printf("\nSum: %f.3", sum);
printf("\nMax: %f.3", max);
printf("\nMin: %f.3", min);
printf("\nMean: %f.3", mean);
}
This code should compile. I suspect something might be wrong with your development environment.
Since you're running Eclipse, I'm assuming that your compiler is GCC. I may be wrong though.
Try to locate your compiler executable, and run the compilation by hand:
gcc -Wall -o simpleStats simpleStats.c
or, if you're on Windows:
gcc.exe -Wall -o simpleStats.exe simpleStats.c
You may have to specify the full path to gcc.exe, (depending on your environment, it might even be called something else; you may be able to retrieve the full path from the console window in Eclipse).
Pay close attention to the output. Copy/paste the full output verbatim in your original post if you can (do not rephrase the warnings / error messages).
I seldom use Eclipse, but with most IDEs you get to chose what kind of project you want to create. Make sure you selected something like "console application", the error you're referring to (stdin not being resolved) may suggest a linker error. Again, it's hard to tell without the exact GCC output.
A couple more things to check:
make sure your compiler and its dependencies are properly installed,
make sure that this compiler is targeted at Windows (or whatever OS you use), not at some exotic embedded platform,
most development environments come with a bunch of sample projects, see if you can build one.
The problem I was having ended up being the compiler not correctly reading the code. I used a different compiler, and with some minor syntax changes, the code worked fine.

Is it possible to effectively parallelise a brute-force attack on 4 different password patterns?

In the context of my homework task I need to smart brute-force a set of passwords. Every password in the set has either of three possible masks:
%%##
##%%
#%%#
%##%
( # - a numeric character, % - a lowercase alpha character ).
At this point I am doing something like this to run over only one pattern ( the 1st one ) in multithreading:
// Compile: $ gcc test.c -o test -fopenmp -O3 -std=c99
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>
int main() {
const char alp[26] = "abcdefghijklmnopqrstuvwxyz";
const char num[10] = "0123456789";
register int i;
char pass[4];
#pragma omp parallel for private(pass)
for (i = 0; i < 67600; i++) {
pass[3] = num[i % 10];
pass[2] = num[i / 10 % 10];
pass[1] = alp[i / 100 % 26];
pass[0] = alp[i / 2600 % 26];
/* Slow password processing here */
}
return 0;
}
But, unfortunately, that technique has nothing to do with searching passwords with different patterns.
So my question is:
Is there a way to construct an effective set of parallel for instructions in order to run the attack simultaneously on each password pattern?
Help is much appreciated.
The trick here is to note that all four password options are simply rotations/shifts of each other.
That is, for the example password qr34 and the patterns you mention, you are looking at:
qr34 %%## #Original potential password
4qr3 #%%# #Rotate 1 place right
34qr ##%% #Rotate 2 places right
r34q %##% #Rotate 3 places right
Given this, you can use the same generation technique as in your first question.
For each potential password generated, check the potential password as well as the next three shifts of that password.
Note that the following code relies on an interesting property of C/C++: if the truth value of a statement can be deduced early, no further execution takes place. That is, given the statement if(A || B || C), if A is false, then B must be evaluated; however, if B is true, then C is never evaluated.
This means that we can have A=CheckPass(pass) and B=CheckPass(RotatePass(pass)) and C=CheckPass(RotatePass(pass)) with the guarantee that the password will only be rotated as many times as necessary.
Note that this scheme requires that each thread have its own, private copy of the potential password.
//Compile with, e.g.: gcc -O3 temp.c -std=c99 -fopenmp
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int PassCheck(char *pass){
return strncmp(pass, "4qr3", 4)==0;
}
//Rotate string one character to the right
char* RotateString(char *str, int len){
char lastchr = str[len-1];
for(int i=len-1;i>0;i--)
str[i]=str[i-1];
str[0] = lastchr;
return str;
}
int main(){
const char alph[27] = "abcdefghijklmnopqrstuvwxyz";
const char num[11] = "0123456789";
char goodpass[4] = "----"; //Provide a default password to indicate an error state
#pragma omp parallel for collapse(4)
for(int i = 0; i < 26; i++)
for(int j = 0; j < 26; j++)
for(int m = 0; m < 10; m++)
for(int n = 0; n < 10; n++){
char pass[4] = {alph[i],alph[j],num[m],num[n]};
if(
PassCheck(pass) ||
PassCheck(RotateString(pass,4)) ||
PassCheck(RotateString(pass,4)) ||
PassCheck(RotateString(pass,4))
){
//It is good practice to use `critical` here in case two
//passwords are somehow both valid. This won't arise in
//your code, but is worth thinking about.
#pragma omp critical
{
memcpy(goodpass, pass, 4);
//#pragma omp cancel for //Escape for loops!
}
}
}
printf("Password was '%.4s'.\n",goodpass);
return 0;
}
I notice that you are generating your password using
pass[3] = num[i % 10];
pass[2] = num[i / 10 % 10];
pass[1] = alp[i / 100 % 26];
pass[0] = alp[i / 2600 % 26];
This sort of technique is occasionally useful, especially in scientific programming, but usually only for addressing convenience and memory locality.
For instance, an array of arrays where an element is accessed as a[y][x] can be written as a flat-array with elements accessed as a[y*width+x]. This gives a speed gain, but only because the memory is contiguous.
In your case, this indexing does not produce any speed gains, but does make it more difficult to reason about how your program works. I would avoid it for this reason.
It's been said that "premature optimization is the root of all evil". This is especially true of micro-optimizations such as the one you're trying here. The biggest speed gains come from high-level algorithmic decisions, not from fiddly stuff. The -O3 compilation flag does most of everything you'll ever need done in terms of making your code fast at this level.
Micro-optimizations assume that doing something convoluted in your high-level code will somehow enable you to out-smart the compiler. This is not a good assumption since the compiler is often quite smart and will be even smarter tomorrow. Your time is very valuable: don't use it on this stuff unless you have a clear justification. (Further discussion of "premature optimization" is here.)

Seg Fault when initializing array

I'm taking a class on C, and running into a segmentation fault. From what I understand, seg faults are supposed to occur when you're accessing memory that hasn't been allocated, or otherwise outside the bounds. 'Course all I'm trying to do is initialize an array (though rather large at that)
Am I simply misunderstanding how to parse a 2d array? Misplacing a bound is exactly what would cause a seg fault-- am I wrong in using a nested for-loop for this?
The professor provided the clock functions, so I'm hoping that's not the problem. I'm running this code in Cygwin, could that be the problem? Source code follows. Using c99 standard as well.
To be perfectly clear: I am looking for help understanding (and eventually fixing) the reason my code produces a seg fault.
#include <stdio.h>
#include <time.h>
int main(void){
//first define the array and two doubles to count elapsed seconds.
double rowMajor, colMajor;
rowMajor = colMajor = 0;
int majorArray [1000][1000] = {};
clock_t start, end;
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
start=clock();
//first we do row major
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j<1000; j++)
{
majorArray[i][j] = 314;
}
}
end=clock();
rowMajor+= (end-start)/(double)CLOCKS_PER_SEC;
//at this point, we've only done rowMajor, so elapsed = rowMajor
start=clock();
//now we do column major
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j<1000; j++)
{
majorArray[j][i] = 314;
}
}
end=clock();
colMajor += (end-start)/(double)CLOCKS_PER_SEC;
}
//now that we've done the calculations 100 times, we can compare the values.
printf("Row major took %f seconds\n", rowMajor);
printf("Column major took %f seconds\n", colMajor);
if(rowMajor<colMajor)
{
printf("Row major is faster\n");
}
else
{
printf("Column major is faster\n");
}
return 0;
}
Your program works correctly on my computer (x86-64/Linux) so I suspect you're running into a system-specific limit on the size of the call stack. I don't know how much stack you get on Cygwin, but your array is 4,000,000 bytes (with 32-bit int) - that could easily be too big.
Try moving the declaration of majorArray out of main (put it right after the #includes) -- then it will be a global variable, which comes from a different allocation pool that can be much bigger.
By the way, this comparison is backwards:
if(rowMajor>colMajor)
{
printf("Row major is faster\n");
}
else
{
printf("Column major is faster\n");
}
Also, to do a test like this you really ought to repeat the process for many different array sizes and shapes.
You are trying to grab 1000 * 1000 * sizeof( int ) bytes on the stack. This is more then your OS allows for the stack growth. If on any Unix - check the ulimit -a for max stack size of the process.
As a rule of thumb - allocate big structures on the heap with malloc(3). Or use static arrays - outside of scope of any function.
In this case, you can replace the declaration of majorArray with:
int (*majorArray)[1000] = calloc(1000, sizeof majorArray);
I was unable to find any error in your code, so I compiled it and run it and worked as expected.
You have, however, a semantic error in your code:
start=clock();
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
Should be:
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
start=clock();
Also, the condition at the end should be changed to its inverse:
if(rowMajor<colMajor)
Finally, to avoid the problem of the os-specific stack size others mentioned, you should define your matrix outside main():
#include <stdio.h>
#include <time.h>
int majorArray [1000][1000];
int main(void){
//first define the array and two doubles to count elapsed seconds.
double rowMajor, colMajor;
rowMajor = colMajor = 0;
This code runs fine for me under Linux and I can't see anything obviously wrong about it. You can try to debug it via gdb. Compile it like this:
gcc -g -o testcode test.c
and then say
gdb ./testcode
and in gdb say run
If it crashes, say where and gdb tells you, where the crash occurred. Then you now in which line the error is.
The program is working perfectly when compiled by gcc, & run in Linux, Cygwin may very well be your problem here.
If it runs correctly elsewhere, you're most likely trying to grab more stack space than the OS allows. You're allocating 4MB on the stack (1 mill integers), which is way too much for allocating "safely" on the stack. malloc() and free() are your best bets here.

Resources