Matrix not zero-filled on declaration - c

I was trying to debug my code in another function when I stumbled upon this "weird" behaviour.
#include <stdio.h>
#define MAX 20
int main(void) {
int matrix[MAX][MAX] = {{0}};
return 0;
}
If I set a breakpoint on the return 0; line and I look at the local variables with Code::Blocks the matrix is not entirely filled with zeros.
The first row is, but the rest of the array contains just random junk.
I know I can do a double for loop to initialize manually everything to zero, but wasn't the C standard supposed to fill this matrix to zero with the {{0}} initializer?
Maybe because it's been a long day and I'm tired, but I could've sworn I knew this.
I've tried to compile with the different standards (with the Code::Blocks bundled gcc compiler): -std=c89, -std=c99, std=c11 but it's the same.
Any ideas of what's wrong? Could you explain it to me?
EDIT:
I'm specifically asking about the {{0}} initializer.
I've always thought it would fill all columns and all rows to zero.
EDIT 2:
I'm bothered specifically with Code::Blocks and its bundled GCC. Other comments say the code works on different platforms. But why wouldn't it work for me? :/
Thanks.

I've figured it out.
Even without any optimization flag on the compiler, the debugger information was just wrong..
So I printed out the values with two for loops and it was initialized correctly, even if the debugger said otherwise (weird).
Thanks however for the comments

Your code should initialize it to zero. In fact, you can just do int matrix[MAX][MAX] = {};, and it will be initialized to 0. However, int matrix[MAX][MAX] = {{1}}; will only set matrix[0][0] to 1, and everything else to 0.
I suspect what you are observing with Code::Blocks is that the debugger (gdb?) is not quite showing you exactly where it is breaking in the code - either that or some other side-effect from the optimizer. To test that theory, add the following loop immediately after the initialization:
``` int i,j;
for (i = 0; i < MAX; i++)
for (j = 0; j < MAX; j++)
printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);
```
and see if what it prints is consistent with the output of the debugger.
I am going to guess that what might be happening is that since you are not using matrix the optimizer might have decided to not initialize it. To verify, disassemble your main (disass main in gdb and see if the matrix is actually being initialized.

Related

Understanding the reason behind a output

I am a beginner is Computer Science and I recently started learning the language C.
I was studying the for loop and in the book it was written that even if we replace the initialization;testing;incrementation statement of a for loop by any valid statement the compiler will not show any syntax error.
So now I run the following program:
#include<stdio.h>
int main()
{
int i;
int j;
for(i<4;j=5;j=0)
printf("%d",i);
return 0;
}
I have got the following output.
OUTPUT:
1616161616161616161616161616161616161616.........indefinitely
I understood why this is an indefinite loop but i am unable to understand why my PC is printing this specific output? Is there any way to understand in these above kind of programs what the system will provide us as output?
This is a case of undefined behaviour.
You have declared i so it has a memory address but haven't set the value so its value is just whatever was already in that memory address (in this case 16)
I'd guess if you ran the code multiple times (maybe with restarts between) the outputs would change.
Some more information on uninitialized variables and undefined behaviour: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/
Looks like i was never initialized, and happens to contain 16, which the for loop is printing continuously. Note that printf does not add a new line automatically. Probably want to read the manual on how to use for.
To better understand what is going on, you can add additional debugging output to see what other variables are set to (don't forget the \n newline!) but really problem is the for loop doesn't seem right. Unless there's something going on with j that you aren't showing us, it really doesn't belong there at all.
You are defining the variable i but never initializing it, instead, you are defining the value for j but never using it.
On a for loop, first you initialize the control variable, if you haven't already done it. Then you specify the condition you use to know if you should run another iteration or not. And last but not least, change the value of the control variable so you won't have infinite loops.
An example:
#include <stdio.h>
int main()
{
// 1. we declare i as an integer starting from 1
// 2. we will keep iterating as long as i is smaller than 10
// 3. at the end of each iteration, we increment it's value by 1
for (int i = 1; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}

expression did not evaluate to a constant ERROR code

So I am trying to learn C and I am trying to make this code so it will sort of the array's elements from lowest to highest, it's obviously not complete but I just wanted to see the random numbers printed.
Anyway, I am getting an error E0028 & C2131 (Visual Studios) that says "expression must have a constant value" & "expression did not evaluate to a constant." The int goals[howMany];is where VS is telling me I have an error
int main()
{
int i, temp, swapped;
int howMany = 10;
int goals[howMany];
for (i = 0; i < howMany; i++) {
goals[i] = (rand() % 25) + 1;
}
printf("Original List\n");
for (i = 0; i < howMany; i++) {
printf("%d \n", goals[i]);
}
return 0;
}
This is exactly how the code is written out in the tutorial I am watching and they are using Code:Blocks. I know sometimes those two compilers can be different but I was hoping someone can let me know what's going on or how to fix this.
Visual studio doesn't support variable length arrays. C is a little tricky, and the compiler/flags you use matters. For example, if you were to compile with the gcc compiler, using the -std=c99 flag would allow you to run your code with no errors (since -std=c99 supports variable length arrays).
I'm not sure exactly how compilation in Visual Studio works, but that's your problem. I usually don't like C programming in VS for this reason. It's much easier for me to use something like Vim, and compile at the command like so that I can specify compiler settings.
In order to use rand(), you need to include the according lib and then "plant a rand seed" : take a look at C Rand Function
const howMany = 10;
This most likely is just the compiler you are using. I suppose it's a safe guard to prevent a segmentation fault. If howMany variable is changed after being used to initialize the array then a seg fault will will definitely result.A seg fault is when you access something out of bounds. If you try to change a const variable then the compiler will not let you.By making howMany const this will prevent any such errors.

Why with base index 1 C program works fine?

This may be a naive question but as per my understanding I know that by deafult base index of an array starts with zero.
What I don't understand is that why the following program working fine when used base 1 indexing.
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("%d",a[n]);
return 0;
}
What I don't understand is that why the following program working fine
it's just bad luck.
This is undefined behaviour. That means the compiler doesn't have to warn you, and no code is emitted to check it at runtime.
Undefined means completely undefined, which includes working, and appearing to work until after you ship it to a customer, as well as the more obvious locking up your machine, formatting all the disks and setting fire to your PSU.
Your code will compile but you won't get expected results.
First element of array a will not be printed and one garbage value will be printed at end of array as there is no bound checking for arrays in c.

How do I implement functions in the C language?

I'm have a really hard time completing some homework, and would appreciate if anyone could sent me on the right path.
Basically, I've been asked to define a function that counts the number of iterations that occurs until a number grows larger than 10 or some number (max). I've made the function like this:
#include <stdio.h>
int iteration(float x, int max){
int n;
float y;
for (n=0;y=0;n++) {
y=y+x;
if (y>=10,max) {
break;
}
}
return n;
}
First off I'm not even sure if the if statement is correct (I don't know if it's proper code to just put a comma for "or"). After that, I'd imagine the rest of the code is okay (clarification would be greatly appreciated!).
Once this was done, I made a header file (Count.h where this file was Count.c) with just:
#include <stdio.h>
int iteration(float x, int max);
And finally, I used this header in a different file, which was just the header and then the main function like:
int main () {
iteration (9.8, 5);
return 0;
}
Everything compiles fine (but not through the "make" command, when I use icc individually to create each object file, it works), but nothing gets outputted or executed.
If someone can let me know where I'm going wrong, I'd really appreciate it! Or if you could give me a hint, I'm sure I could figure it out. I'm getting stressed because this is just the first part of a long homework assignment, and I can't believe I can't even figure this simple stuff out!
Thanks in advance!
this isn't a great question, and I would normally just comment, but I find it harder to format comments... here is the problem, probably...
for (n=0;y=0;n++)
so in C = is the assignment operator, and == tests equality... so the resulting expression y=0 will always evaluate to false... so this for loop will never be entered (equivalent is while(0))
it looks like you don't actually care about that term, so you can either leave it blank or make it a true value... or just make it the exit criteria, so ....
assert (x>0.0); // otherwise the loop will never exit
for (int i = 1; ; i++) // more idiomatic to use i as a loop counter
{
y+=x;
if (y > max)
{
return i;
}
}
return 0; // already over max
so you need:
float y = 0;
get rid of n it isn't doing anything.
or alternately you may have meant something like...
for( n=0,y=0;;n++)
which is fine but a little weird and complicated
To clarify, did you include your header in your main .C file (i.e. #include "Count.h")?
Also, you have iteration return 'n', but do nothing with it. You must either assign the returned integer to a variable (answer = iteration (9.8, 5);) or output it (printf("%i", iteration (9.8, 5))).
As long as you've included your header, your program is most likely executing as expected, but with nothing done with the returned value, it just ends without outputting anything.

Understanding the logic of nested for-loops

I wrote a program where the user inputs numbers n times; the program prints out the the numbers removing all duplicates.
On the code you will see that I initialized seen = 0 at the beginning of the code and when I do so without initializing again on my for loop It won't print out the numbers correctly but when I do it will. Can somebody explain why? I would really like to understand this.
I clarified my question on the code itself. Have a look:
#include <stdio.h>
int main()
{
int arr[100];
int i, j, num, seen = 0; // here is where I first initialized it
// but I see that this is not necessary
printf("Enter Number: ");
scanf("%d", &num);
for (i=0; i<num; i++)
{
printf("Arr[%d] ", i);
scanf("%d", &arr[i]);
}
for (i=0; i<num; i++)
{
//seen = 0; If I initialize it here
// it will print out the numbers correctly
for (j=0; j<i; j++)
{
if (arr[i]==arr[j])
{
seen = 1;
break;
}
}
if (!seen)
printf("%d", arr[i]);
}
printf("\n");
}
If you don't reset seen=0 in the outer loop, the program thinks that it has seen every one after the first one that it finds.
Googling gdb tutorial yielded this that looks promising.
Think about what the value of your seen variable means.
You iterate over the array of numbers. For each number, you do the following:
Loop over the previous numbers in the array, and check whether the current number has already been seen.
Print the current number only if it hasn't already been seen.
seen should be true only if you've already seen the current number. The way your program is currently written, it remains true as long as the program continues to run, though the old value becomes irrelevant as soon as the outer loop advances to a new number.
In fact, it would be even better to move the declaration of seen (along with its initialization to 0 inside the outer loop. Since its value is not meaningful outside one iteration of the outer loop, it might as well only exist within each iteration of the outer loop.
(Running your program under a source level debugger such as gdb is one way to find errors like this, but not the only one. Re-reading your code and reasoning about what it does vs. what it should do is another useful approach. Adding printf calls to show the values of variables as the program runs is another.)
Please learn about debugger programs.
In an IDE like Visual Studio or Eclipse it is built in.
Using GCC on Linux command line it is called gdb. You compile your program with the -g flag to make GCC include debug information. Then you run gdb program-name and start and n, then hit return as it steps through the program. There are also many other commands.
With that you should be able to solve this problem and many others.

Resources