Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
This block of code gives me the fibonacci numbers
#include <stdio.h>
int main()
{
int n; //integer overflow error for n > 47
printf("How many Fibonacci numbers?\n");
scanf("%d", &n);
int fibs[n];
fibs[0] = 0;
fibs[1] = 1;
printf("%d ", fibs[0]);
printf("%d ", fibs[1]);
for(int i = 2; i < n; i++)
{
fibs[i] = fibs[i - 2] + fibs[i - 1];
printf("%d ", fibs[i]);
}
return 0;
//gives 0 1 1 2 3 5 8 13 21 34 for n = 10
}
But this gives me the wrong output but no errors
#include <stdio.h>
int main()
{
int n, fibs[n];//change
printf("How many Fibonacci numbers?\n");
scanf("%d", &n);
fibs[0] = 0;
fibs[1] = 1;
printf("%d ", fibs[0]);
printf("%d ", fibs[1]);
for(int i = 2; i < n; i++)
{
fibs[i] = fibs[i - 2] + fibs[i - 1];
printf("%d ", fibs[i]);
}
return 0;
//gives 0 1 for n = 10
}
I know it definitely has something to do with the array and its size not being defined but I'm having trouble understanding what exactly is the problem.
Could someone explain what is going on here?
int n, fibs[n]; attempts to define an array using n for the length, but n has not been initialized, so its value is not determined. Common consequences include:
The definition behaves as if n has some small value, possibly zero, and then the following code attempts to store values in the array but overruns the memory reserved for it and thus destroys other data needed by the program.
The definition behaves as if n has some large value, causing the stack to overflow and the program to be terminated.
For example, storing 0 to to fibs[0] or 1 to fibs[1] might write to the memory reserved for n. Then the for loop terminates without executing any iterations because the test i < n is false.
The one big thing that I see in your code is the line int n, fibs[n];. The variable n is located on the stack since it's a local variable. That means that it's value can literally be anything before it's initialized. And since you are declaring an array using that value, the array has a random, unknown length. If it works, then that is purely coincidence. This is why your first code version works because the array is declared AFTER the scanf which initializes n. I think a better way of creating an array with a variable number of array elements is to use malloc instead...
int n, *fibs;
printf("How many Fibinocci numbers?\n");
scanf("%d", &n);
fibs = malloc(sizeof(int) * n);
if (fibs == NULL)
{
fprintf(stderr, "Unable to allocate sufficient memory for operation.\n");
exit(1);
}
Then you can use array indices fibs[0], fibs[1], etc... to access different locations in the block of memory.
Why does this work? Because int fibs[n] is LIKE a pointer to a block of memory. Technically, they are not the same, but you can generally use a pointer to a block of memory as an array. This will only work with single dimensional arrays because the compiler has no idea how many columns there are. But to work around that, you can compute that manually like this (i is the row, j is the column):
array[i * columns + j];
Related
This question already has an answer here:
Why the size of pointer to array is always 8 in C? [duplicate]
(1 answer)
Closed 3 years ago.
I'm making a program capable to use some statistics functions. For that, I used malloc for the array that the numbers of the sample to operate on, as I want it's size to be based on users' input. It's not the first time I do this, and it worked fine, but this time I can't set the size as needed and I can't find the flaw.
Below is the necessary code for the creation and printing of the array, skipping main() as it only runs the functions.
int *sample;
int MakeSample()
{
int sampleSize;
int valueN;
printf("Enter size of your sample: ");
scanf("%d", &sampleSize);
sample = malloc(sampleSize * sizeof(int));
for (int i = 1; i <= sampleSize; i++)
{
printf("Enter value #%d: ", i);
scanf("%d", &valueN);
sample[i - 1] = valueN;
}
}
int PrintSample()
{
for (int k = 1; k <= sizeof(sample); k++)
{
printf("Value #%d: %d\n", k, sample[k - 1]);
}
}
If I enter size 1 for the array, that should be the amount off values asked for and printed, instead I got this:
Value #1: 1
Value #2: 0
Value #3: 0
Value #4: 0
Value #5: 0
Value #6: 0
Value #7: 133057
Value #8: 0
sample is an int pointer; sizeof(sample) is always 8. You need to store the sampleSize variable somewhere and use that instead - there's no way for your program to know how big your array is otherwise, since it's not really an "array", it's a pointer to memory that happens to hold an array.
This question already has answers here:
int LA[] = {1,2,3,4,5} memory allocation confusion in c
(3 answers)
Closed 6 years ago.
So. I am teaching programming 1 to some college level pupils at the moment. And i specifically told them to go out and look online for references, specifically on the datastructure parts i am covering at the moment. Today one student emailed me with a link to tutorialspoint.com and asked about this piece of code he pulled from there:
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int item = 10, k = 3, n = 5;
int i = 0, j = n;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
n = n + 1;
while( j >= k) {
LA[j+1] = LA[j];
j = j - 1;
}
LA[k] = item;
printf("The array elements after insertion :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
}
Now, without knowing exactly where it's from i don't know exactly how they described it, but obviously it is insertion into an array of value at index k, shuffling upwards from k.
Now what he asked about was that i have told my students that when doing something like:
int arr[] = {1,2,3,4};
the compiler will auto-count the size, by checking the supplied value list. This case means an array size of 4 elements. I have also told them that an array size is fixed when the array is first initialized, like:
int likethis[5];
int orthis[] = {1,2,3,4};
int orlikeso[MAX_ARR_SIZE];
Thus, to resize an array, dynamic memory management is needed, so that you would declare space for a new array (a part of the course they have yet to get to).
But the code from this tutorial site actually seems to do an auto-size by the compiler with the initializer list, then go about merrily resizing it in the loop, when shuffling.
So the final size of LA in their example would be 6 elements. Now, my student wants to know why this is valid. I have not tested this code myself, but apperantly it compiles on GCC according to my student. If so, how can that code be valid? Wouldn't this overwrite the boundaries of LA, when setting LA[5] in the shuffle loop?
Questions: Is it me who is an old geezer, and this is allowed in C since way back? Only in GCC? Seeing as i learned C in the 80s somewhere, i assume i might be wrong here, but to me it is writing past the assigned size of LA. Just wanted to check it on S.O.
But the code from this tutorial site actually seems to do an auto-size by the compiler with the initializer list, then go about merrily resizing it in the loop, when shuffling.
The code only appears to do that. In reality, the code causes undefined behavior as soon as it touches index 5 of a five-element array.
Now, my student wants to know why this is valid.
He should have started with a simpler "is this valid" question. The answer to it would be "no". The code will compile, and may even appear to work, but this code is invalid.
Unfortunately, there is no easy way to demonstrate it to students at the early stages of learning C, because reading memory profiler reports (say, valgrind) is an advanced skill. On the other hand, if the students have enough determination to learn how to run their code through a memory profiler, they are in for a very rewarding experience of having good confidence in their code.
Note: I think this is a great teaching moment, because it lets you teach the student an important point about undefined behavior in C, and also reinforce the rule "you shouldn't trust things just because you found them on the internet" applies to code as well.
By attempting to write past the last element of the array, the code invokes undefined behavior, which means it may crash outright, silently corrupt data, or appear to run without any problems.
There may be some padding or scratch space that the extra element is being written to, which is why it isn't crashing, but this code is not valid.
To answer your question, the code is simply not valid. The array overflows but the bug is not visible (however if you enable compiler size optimization, it should improve probabilities that this code crashes).
In order to help you spotting the overflow, i suggest you run the code with Valgrind, as it will spot the overflow for you.
edit: I ran Valgrind with memcheck and it didn't spot that overflow. Surprising for me.
There is nothing as automatic resizing with arrays in C. What is happening here is something known as "buffer overflow" . (Check the answer at Memory confusion for strncpy in C for more details on possible side effects of buffer overflow)
To show that the size of LA has not changed at all you can try printing the size at the beginning and at the end of the code as below:
#include <stdio.h>
int main() {
int LA[] = {1,3,5,7,8};
int item = 10, k = 3, n = 5;
int i = 0, j = n;
printf("The original array elements are :\n");
printf("Number of elements in LA = %ld\n",(sizeof(LA)/sizeof(int)));
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
n = n + 1;
while( j >= k) {
LA[j+1] = LA[j];
j = j - 1;
}
LA[k] = item;
printf("The array elements after insertion :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
printf("Number of elements in LA = %ld\n",(sizeof(LA)/sizeof(int)));
}
I have observed that memory allocated for array seems to be dynamic.
Here is the sample code I found in this tutorial:
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int item = 10, k = 3, n = 5;
int i = 0, j = n;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
n = n + 1;
while( j >= k){
LA[j+1] = LA[j];
j = j - 1;
}
LA[k] = item;
printf("The array elements after insertion :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
}
and sample output:
The original array elements are :
LA[0]=1
LA[1]=3
LA[2]=5
LA[3]=7
LA[4]=8
The array elements after insertion :
LA[0]=1
LA[1]=3
LA[2]=5
LA[3]=10
LA[4]=7
LA[5]=8
How its working I did not get.
First, a general statement, for an array defined without explicit size and initialized using brace-enclosed initializer, the size will depend o the elements in the initializer list. So, for your array
int LA[] = {1,3,5,7,8};
size will be 5, as you have 5 elements.
C uses 0-based array indexing, so the valid access will be 0 to 4.
In your code
LA[j+1] = LA[j];
trying to access index 6, (5+1) which is out of bound access. This invokes undefined behavior.
Output of a code having UB cannot be justified in any way.
That said, main() is technically an invalid signature as per latest C standards. You need to use at least int main(void) to make the code conforming for a hosted environment.
The code has a buffer overflow bug! Arrays in C cannot be extended! You need to allocate enough space when you declare/define it.
You can declare additional space by supplying a size in the declaration:
int LA[10] = {1,3,5,7,8};
LA will now have room for 10 elements with index 0 through 9.
If you want more flexibility you should use a pointer and malloc/calloc/realloc to allocate memory.
Note:
There is a second bug in the copying. The loop starts one step too far out.
With j starting at 5 and assigning index j+1 the code assigns LA[6], which is the 7th element. After the insertion there are only 6 elements.
My conclusion from these 2 bugs is that the tutorial was neither written nor reviewed by an experienced C programmer.
To add on to the other answers, C/C++ do not do any bounds checking for arrays.
In this case you have a stack allocated array, so as long as your index does not leave stack space, there will be no "errors" during runtime. However, since you are leaving the bounds of your array, it is possible that you may end up changing the values of other variables that are also allocated in the stack if it's memory location happens to be immediately after the allocated array. This is one of the dangers of buffer overflows and can cause very bad things to happen in more complex programs.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to sum an array of numbers. The array has a length determined by an input and then the user gives the array. There were no compilation errors and I am able to run other programs. On the immediate start of running the program I am given a message that program has stopped working and that windows is searching for solution.
#include <stdio.h>
int main()
{
int sum, length, count;
int array[length];
sum=0;
scanf("%d",&length);
scanf("%d",&sum);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
When you declare your array it depends on length but you ask the user for length after.
A solution could be to ask the user for length (scanf("%d",&length);) before declaring your actual array (int array[length];).
you should move int array[length] to after scanf("%d", &length). But it is not allowed in C to declare variables after the first non-declaration (it is however possible if you compile this program as C++).
In fact, in standard C you can't have a non-const length definition for an array variable. gcc on the other hand for example allows this nevertheless.
In your case, the problem is that length has an undefined value at the declaration of int array[length];. If you are lucky, your data segment has been initialized to zero (there is no guarantee for that) but otherwise, it may be any value, including a value which leads the program to exceed your physical memory.
A more standard way of doing this is:
int *array = NULL;
scanf("%d",&length);
...
array = (int*) malloc(sizeof(int) * length);
...
free(array);
By the way, even after fixing that, you will most likely get random numbers because you never actually assign the contents of the elements of array.
Local variable are initialized to 0. Hence value of length is 0. So you array is of length. You are then reading length, say 10, from stdin and expect the array to be of length 10. This can't be. Since this is a stack variable, the size is determined in time of pre-processing and not in run time. If you want to define the array length in run time then use malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int sum, length, count;
int *array;
sum=0;
scanf("%d", &length);
scanf("%d",&sum);
array = (int *)malloc(sizeof(int) * length);
if (array == NULL) return 0;
memset(array, length, 0);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
Thanks.
first problem:
the length variable is being used to set the number of entries in the array[], before the variable length is set. Therefore, length will contain what ever trash happens to be on the stack when the program starts so the number of entries defined in array[] is an unknown.
This results in undefined behaviour and could lead to a seg fault event, depending on what was on the stack and what the user entered for length.
second problem:
The array array[] is never initialized so will contain what ever trash is on the stack at program startup. This means the value being printed could be anything. And the 'sum' could overflow, depending on the trash values in array[]
OP program lacks the part of data input, it's asking for sum instead of the values to sum, which is weird. The only inputs requested are also never checked (the return value of scanf must always be checked).
In C (at least C99 and optionally C11) Variable Length Arrays, like the one defined by int array[length], can be used, but the variable length here is used uninitialized and before it is even asked to the user.
Moreover, the loop where the sum is calculated stops before the last element of the array (not really a big deal in this case, considering that all those variables are uninitialized...).
A better way to perform this task could be this:
#include <stdio.h>
// helper function to read an integer from stdin
int read_int( int *value ) {
int ret = 0;
while ( (ret = scanf("%d", value)) != 1 ) {
if ( ret == EOF ) {
printf("Error: Unexpected end of input.\n");
break;
}
scanf("%*[^\n]"); // ignore the rest of the line
printf("Please, enter a number!\n");
}
return ret;
}
int main(void) {
int sum = 0,
length = 0,
count,
i;
printf("Please, enter the number of values you want to add: ");
if ( read_int(&length) == EOF )
return -1;
// Use a VLA to store the numbers
int array[length];
// input the values
for ( count = 0; count < length; ++count ) {
// please, note ^^^^^^^^ the range check
printf("Value n° %2d: ", count + 1);
if ( read_int(&array[count]) == EOF ) {
printf("Warning: You entered only %d values out of %d.\n",
count, length);
break;
}
// you can sum the values right here, without using an array...
}
// sum the values in the array
for ( i = 0; i < count; ++i ) {
// ^^^^^^^^^ sum only the inputted values
sum += array[i];
}
printf("The sum of the values is:\n%d\n", sum);
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've been tasked to code a program that processes a simple 1D array to return its element values, but the compiler has been behaving strangely; outputting more values than I have array elements.. It's also not being fully compliant with one of my statements (one that prints a new line character every 8 elements) and not assigning the largest value to my variable. I think that the other two problems will go away once the first problem is fixed, however.
Here is my brief:
Design, code and test a program that:
Fills a 20 element array (marks) with random numbers between 0 and 100.
Prints the numbers out 8 to a line
Prints out the biggest number, the smallest number and the average of the numbers
And here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int marks[20];
int i = 0;
int sum = 0;
int min;
int max;
for(i;i<=sizeof(marks);i ++){
marks[i] = rand() % 100;
sum += marks[i];
if(i % 8 == 0){
printf("\n");
}
printf("%d ", marks[i]);
if(marks[i]>max){
max = marks[i];
}
else if(marks[i]<min){
min = marks[i];
}
}
printf("\n\nThe minimum value is: %d", min);
printf("\nThe maximum value is: %d", max);
printf("\n\nThe average value is: %d", sum / sizeof(marks));
return 0;
}
Please can someone help me get the correct output?
sizeof() function returns the byte length of the array, so this code "thinks" your array is 20 * whatever byte size ints are on your machine. You will want to just use i < 20 in the loop or go
for (i;i<sizeof(marks)/sizeof(int); i ++) { ...
Note that you probably do not want the <= operator in the for loop, since arrays are 0 indexed, thus marks[20] is actually one beyond the array.
There are two problem I can see that will invoke undefined behavior in your code.
By saying for(i;i<=sizeof(marks);i ++), you're out of bounds.
int min; int max; are not initialized and you're attempting to use it.
to solve this.
Change the for loop condition to for(i; i< 20; i++). Better to use a preprocessor construct like #define SIZ 20 and then make use of it accross your code to make it consistent and robust.
Initialize your local variables. max should be INT_MIN, and min can be INT_MAX. (see limits.h for reference).
To clarify more on point 2, max and min are automatic local variables, and in case not initialized explicitly, it contains indeterminate values.
C11, chapter §6.7.9,
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
and then, directly from the Aneex J, §J.2, Undefined behaviour,
The value of an object with automatic storage duration is used while it is
indeterminate.
if(marks[i]>max){
max = marks[i];
}
else if(marks[i]<min){
min = marks[i];
}
min and max are not initialized here. Make sure to set your compiler warnings at the highest level, so you get a warning message when you forget to initialize variables.
for(i;i<=sizeof(marks);i ++){
This doesn't make sense. Replace sizeof(marks) with the number of times you want to loop, and use < instead of <=.
For example:
const int num_marks = 20; // or use #define
int marks[num_marks];
for(i = 0; i < num_marks; i++) {}