C++ Why is the output of this code 3? (structs) - c++

Can someone help me understand step-by-step why the following C++ code outputs a 3?
#include <iostream>
using namespace std;
struct sct
{
int t[2];
};
struct str
{
sct t[2];
};
int main() {
str t[2] = { {0,2,4,6}, {1,3,5,7} };
std::cout << t[1].t[0].t[1];
}

t[1] is {1,3,5,7}.
str is represented in memory as four integers back-to-back, organized into 2 sct structures. In this case, the first one has the values 1 and 3, while the second contains 5 and 7.
Thus, t[1].t[0] is {1,3}, so t[1].t[0].t[1] is 3.

str t[2] = { {0,2,4,6}, {1,3,5,7} };
This means we are an array of two str values {0,2,4,6} at 0 index and {1,3,5,7} at index 1.
cout<<t[0] //gives 0,2,4,6
cout<<t[1] //gives 1,3,5,7
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1] i.e (1,3,5,7), and with that we go inside the str block to assign t[1] to a variable of type stc. Inside it there, we find another variable t[2] of type stc. Here we divide our previous value as t[1].t[0]=1,3 and t[1].t[1]=5,7.
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1].t[0]=1,3, and with that we go inside the stc block to assign t[1].t[0] to a variable of type int. Inside it there, we find another variable t[2] of type int. Here we divide our previous value as t[1].t[0].t[0]=1 and t[1].t[0].t[1]=3.
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1].t[0].t[1]=3, and then it gets printed due to cout!!!!!

Related

Palindrome mystery: Why an array of size 3 ends up being printed with 5 elements?

#include <iostream>
#include <cstring>
using namespace std;
int main(){
char a[] = "abc";
char b[2];
for(int i = 0,k = 2;i < 3;i++,k--){
b[k] = a[i];
cout << i << " " << k << endl;
}
if(strcmp(a,b) == 0){
cout << "palindrome";
}else{
cout << "no palindrome" << endl;
}
cout << "a: " << a << endl;
cout << "b: " << b << endl;
return 0;
}
output:
0 2
1 1
2 0
no palindrom
a: abc
b: cbabc
I don't understand why b array ends up with 5 elements, when the array holds only 3. Additionally, the loop loops only 3 times and this is the output I get.... A mystery.
You have an out-of-bounds array access and also need to be conscious of null-terminating your strings!
Specifically, char b[2]; gives you an array with exactly 2 chars, so only b[0] and b[1] are valid. You also need to account for the null character that should terminate all C-style strings. So to hold "cba" for example you need 4 elements. You can also see this if you print sizeof(a) (should be 4: 'a', 'b', 'c', '\0').
Basically, your program elicits undefined behavior (UB). The simple fix is to make b bigger (the same size as a, which is 4 in this case). The more complete answer is to manage your array lengths more carefully and look at the safer "n" versions of the C manipulation functions such as strncmp
Edit: to be complete, you have 2 sourced of UB. The first is in line b[k] = a[i] when k == 2 because again you have only allocated b[0] and b[1]. The second is when you call strcmp since b has not been properly null-terminated and strcmp will happily read past the array bounds, which it doesn't know.
b is not terminated by a null character (\0), so any string operation on it (like strcmp, or even just printing it with cout runs over until it happens to hit such a character somewhere in the memory. In other words, you are witnessing undefined behavior.
Strictly speaking you have undefined behaviour and any observed behaviour (wrong or seemingly partially correct) is explained by that.
For details and solutions see the other answers.
End of answer.
Now lets look at a speculation on why you might in your environment end up with specifically the output you observe.
Assumption, the memory for your arrays
char a[] = "abc";
char b[2]
looks like an often seen habit of linkers of how to arrange variables:
b[0] non-initialised
b[1] non-initialised
a[0] = 'a'
a[1] = 'b'
a[2] = 'c'
a[3] = '\0'
Note the four (not three) elements of a and the terminator 0.
Your loop, right in the first iteration, attempts to write to the non-existing b[2].
This is already what causes undefined behaviour. Clean discussion ends here.
Let's continue speculating.
Your loop unintentionally writes one place beyond the existing b[1] and ends up clobbering a[0]. By chance it writes the value which happens to be already there, so no change there.
Your loop continues to write, now to existing entries of b.
The speculated result is
b[0] = 'c
b[1] = 'b'
a[0] = 'a' = 'a'
a[1] = 'b'
a[2] = 'c'
a[3] = '\0'
and the loop ends.
Then you try to output a and b.
This is done by outputting all characters found consecutively from the start of the arrays, until a terminator 0 is found.
For a this (luckily in case of the "a") is "abc\0", all from a.
For b this is "bc" from b, followed (on the search for a 0) by "abc\0" from a.
Note that the seemingly correct "a" already is incorrectly from a, not from b.
Ok, when debugging this you can check for address of b[2].
In gdb:
(gdb) p &b[1]
$8 = 0x7fffffffdfe3 "\377abc"
See? If b was null terminated it would start with '\0', but it doesn't, you tell the compiler to use 2 spaces for b. When asked the debugger what's the address of last b character b[1], it not only tells the address, it also shows the char* value represented. As b is a non null terminated (my compiler didn't initialize it), it will continue beyond the boundaries of b!. Suspiciously enough the string of characters finishes with 'a''b''c''\0'. Let's check address of a[0]:
(gdb) p &a[0]
$9 = 0x7fffffffdfe4 "abc"
See? The a field pointed by b is contiguous to a. Now you are making two mistakes here:
You are not properly initializing b.
b reserves 2 slots of memory. If you want to check palindromes of a fixed size of 3 characters you should reserve 4 slots like you did for the null terminated string "abc".
Try changing b declaration from:
char b[2];
To:
char b[] = "xyz";
Your initialization code will set the palindrome as a function of a, so it would do what you intend to.

console outputs smiley face

I have this code:
#include "stdafx.h"
#include <iostream>
typedef struct{
int s1;
int s2;
char c1;
char* arr;
}inner_struc;
int _tmain(int argc, _TCHAR* argv[])
{
inner_struc myinner_struct;
myinner_struct.s1 = myinner_struct.s2 = 3;
myinner_struct.c1 = 'D';
char arr[3] = {1,2,3};
myinner_struct.arr = arr;
std::cout << "first array element: " << myinner_struct.arr[1] << std::endl;
return 0;
}
I wonder why am I getting a smiley face instead of the first array element! what am I doing wrong here? It compiles and runs fine however the output is
first array element: "smiley face"
What does this means?
I am using Visual Studio 2010. Thanks
You are outputing the second element in this array:
char arr[3] = {1,2,3};
You have assigned it the values 1 2 and 3, but the variable is of type char, so it is being interpreted as ascii. If you look up what character has a value of 2 on an ascii chart, you will see that it is a smily face. So it is indeed doing what you asked it to do.
http://mathbits.com/MathBits/CompSci/Introduction/ASCIIch.jpg
What are you expecting the output to be? if you wanted it to be a number, then you will have to add the character representation of that number into the array. ie in stead of 1, 2 or 3 use '1', '2', and '3'
As far, as I can see, you are trying to output the first array element. But instead, you are printing the second one (the arrays are indexed starting from 0, not 1). The second element is 2. Now, please, take a look at this table, as you can see: the number 2 is a smiley face. The problem is that you are outputing a character with code 2, not '2'. In order to output a deuce, make your array look like this:
char arr[3] = {'1','2','3'};
inner_struct.arr is declared as char *, which means it holds an array of characters (bytes). Do you want an array to hold the numbers 1, 2, 3? If so, use int. If you want letters, initialize the array with:
char arr[3] = { 'a', 'b', 'c' };
KC

Storing file data variables in a dimentional array

I have a .txt file which I'm trying to gather data from, that can then be used within variables within my code to be used in other functions.
Here's an example of my text file:
0 10 a namez 1 0
0 11 b namea 1 1
1 12 c nameb 1 1
2 13 d namec 0 1
3 14 e named 1 1
So my file will not always be the same number of lines, but always the same number of variables per line.
I currently have this, to firstly get the length of the file and then change the amount of rows within the array:
int FileLength()
{
int linecount = 0;
string line;
ifstream WorkingFile("file.txt");
while(getline(WorkingFile, line))
{
++linecount;
}
return linecount;
}
int main()
{
string FileTable [FileLength()][6];
}
Firstly I don't know if the above code is correct or how I can add the values from my file into my FileTable array.
Once I have my FileTable array with all the file data in it, I then want to be able to use this in other functions.
I've been able to do:
if(FileTable[2][0] = 1)
{
cout << "The third name is: " << FileTable[2][3] << endl;
}
I understand my code may not make sense here but I hope it demonstrates what I'm attempting to do.
I have to do this for a larger text file and all the 6 variables per line relate to be input to a function.
Hold each line in its own object, this is much clearer:
struct Entry
{
std::array<std::string, 6> items; // or a vector
};
In main:
std::vector<Entry> file_table( FileLength() );
Note that it is a waste of time to read the whole file first in order to find the number of entries. You could just start with an empty vector, and push in each entry as you read it.
Your access code:
if( file_table.size() > 2 && file_table[2].items[0] == "1" )
{
cout << "The third name is: " << FileTable[2].items[2] << endl;
}
I would actually recommend giving the members of Entry names, instead of just having an array of 6 of them. That would make your code more readable. (Unless you really need to iterate over them, in which case you can use an enum for the indices).
You could define an operator[] overload for Entry if you don't like the .items bit.
since the number of lines is dynamic I suggest to use vector instead of array. you can push back your data to the vector line by line until you read eof.
also try to study about OOP a little , it would make your code more understandable.
take look at these:
http://www.cplusplus.com/reference/vector/vector/
http://www.geeksforgeeks.org/eof-and-feof-in-c/

Accessing the value pointed by a pointer

Edit: This question should be considered abandoned. I have flagged this question for deletion as i do not know how to even proceed any more at this point. I thank all of you for your willingness and taking the time out of your day to help me.
I am reading and following the documentation at cplusplus on data structures. I have been trying to figure out why the compiler will not accept " *pfruit.weight; " on my own for hours. It am sure it is something simple that i am missing.
error C2228: left of '.weight' must have class/struct/union
1> type is 'product *'
1> did you intend to use '->' instead?
"The operand to the left of the period (.) is not a class, structure, or union."
So how do i correctly access the value pointed by a pointer member?(Not access a reference)
#include <iostream>
using namespace std;
struct product
{
int weight;
float price;
} ;
int main ()
{
product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
//Access a member of an object to which we have a reference
//equivalent to: (*pfruit).weight
*pfruit.weight; //<------ I am so sorry, i meant This is the problem, i am using a reworded line of code from an example and it isn't compiling and returning the error.
//Access the value pointed by a pointer member called weight;
//equivalent to: *(pfruit.weight)
system("pause");
return 0;
}
This code
struct product
{
int weight;
float price;
} ;
int main ()
{
product * pfruit;
*pfruit.weight;
is an operator precedence error. The rules of C++ are that . has higher precedence than *. *pfruit.weight would be correct if pfruit was a struct and weight was a pointer, but in your code it's the other way around, pfruit is the pointer and weight is just an int. So you need to add brackets to apply the operators the right way around
(*pfruit).weight;
You may use the following statement :
(*pfruit).weight;
Instead of :
*pfruit.weight;
which evaluates at compile-time to the following because of operator precedence :
*(pfruit.weight)
This is wrong because you are dereferencing a non-pointer value and trying
to dereference a pointer with the . operator instead of ->.
EDIT :
Here's some piece of response and informations about pointers and to your question as I understood it.
#include <iostream>
using namespace std;
struct product
{
int *weight;
float price;
};
int main()
{
product afruit;
product *pfruit;
pfruit = &afruit;
// Allocating 10 * sizeof(int) bytes of memory. ptr will now point to the first sizeof(int) bytes
// of the memory pointed by the weight pointer.
pfruit->weight = new int[10];
// The first sizeof(int) bytes of the memory pointed by ptr (equivalent to *ptr) equals now the value 4.
pfruit->weight[0] = 4;
// The second sizeof(int) bytes of memory pointed by ptr (or (*ptr + 1)) equals now 42.
pfruit->weight[1] = 42;
// Dereferencing pfruit AND the pointer to the weight, thus returning the VALUE of the first sizeof(int) bytes of weight (4)
// instead of the value of the pointer to weight (0x8b4e008 for instance).
int value = *(pfruit->weight);
std::cout << "Value of pfruit->weight[0] = " << pfruit->weight[0] << std::endl
<< "Value of pfruit->weight[1] = " << pfruit->weight[1] << std::endl
<< "Value of *(pfruit->weight) = " << *(pfruit->weight) << std::endl
<< "Value of *(pfruit->weight + 1) = " << *(pfruit->weight + 1) << std::endl
<< "Value of ptr = " << std::hex << pfruit->weight << std::endl;
// Prints :
// Value of pfruit->weight[0] = 4
// Value of pfruit->weight[1] = 42
// Value of *(pfruit->weight) = 4
// Value of *(pfruit->weight + 1) = 42
// Value of ptr = 0x8b4e008
//
// Note that ptr[0] == *ptr and ptr[1] == (*ptr + 1)
return (0);
}
once try this u may get it this can be written as pfruit->weight or (*pfruit).weight
(*pfruit).weight;
product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
pfruit is a pointer and has the address of the struct afruit.
We use pfruit->weight when we access struct members using a pointer .
When you use a struct name you use . operator.
Now, pfruit is the pointer . Therefore, the struct itself is *pfruit
*pfruit.weight;
This is interpreted as *(pfruit.weight), because .has higher precedence than *. and you can't use . operator with a pointer on LHS
You have to clearly show that you mean (*pfruit).weight
Bit late to the party, but try this:
It sounds like you are expecting values like 'int weight' to be stored as pointers to data somewhere else in the same way that the product is being referred to via pfruit. Some languages do do this, but in C++ simple data members like your weight and price are going to be stored actually in the product data structure. So, if afruit happens to exist at address 1000 in memory, then pfruit will have the value 1000:
... 1000 1001 1002 1003 ...
--+-----+-----+-----+-----+--
| afruit... | | |
--+-----+-----+-----+-----+--
^
|
pfruit = 1000
This means that your weight (int) and price (float) data members will be stored here, one after the other. (and since an int and float are typically 32 bits in size, i.e. 4 bytes, the memory looks like this:
... 1000 1001 1002 1003 1004 1005 1006 1007 ...
--+-----+-----+-----+-----+-----+-----+-----+-----+--
| afruit... |
| <------ weight -----> | <------ price ------> |
--+-----+-----+-----+-----+-----+-----+-----+-----+--
^
|
pfruit = 1000
Consequently, pfruit also happens to point at the weight data (because it's first in the structure), but the price data is 4 bytes further along.
So, when you say you want to get to the data 'pointed to by weight' it doesn't make sense because it actually turns out that you don't need to because when you access the weight member you are already referring to the weight value. It's right there, in the memory occupied by afruit.
If you ARE trying to get a pointer TO the weight (or cost) data itself (instead of afruit, or actually from pfruit) you can do something like this:
int* pweight = &afruit.weight; //from an actual product object
float* pcost = &pfruit->cost; //via a pointer to a product object
There are now various ways to access the members of the product structure afruit:
afruit.weight = 20; //directly access the structure member
pfruit->weight = 10; //follow the structure pointer
*pweight = 15; //derefernce the int pointer
I hope this helps someone, at least a little bit.
Sam

Initializing 2D int array in run-time

I got the code below from a C++ book, and I cannot figure out how the initialization works.
From what I can see, there is an outer for loop cycling trough the rows, and the inner loop
cycling trough the column. But its is the assignment of the values into the array that I do not understand.
#include <iostream>
using namespace std;
int main()
{
int t,i, nums[3][4];
for(t=0; t < 3; ++t) {
for(i=0; i < 4; ++i) {
nums[t][i] = (t*4)+i+1; //I don't understand this part/line
cout << nums[t][i] << ' ';
}
cout << '\n';
}
return 0;
}
so here are some questions.
I cannot understand the initialization of the 2D int array nums[3][4]. What separates the (t*4)+i+1, so that the compiler knows what to assign where?
How do I know what values will be stored in the rows and columns, based on what values have been assigned?
Why is there an asterisk?
What are the parentheses around t*4 for?
I understand that initialization two-dimensional arrays look like the following example.
#include <iostream>
using namespace std;
int main() {
char str[3][20] = {{"white" "rabbit"}, {"force"}, {"toad"}}; //initialize 2D character array
cout << str[0][0] << endl; //first letter of white
cout << str[0][5] << endl; //first letter of rabbit
cout << str[1][0] << endl; //first letter of force
cout << str[2][0] << endl; //first letter of toad
return 0;
}
And from what I know, like this in memory.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 w h i t e r a b b i t 0
1 f o r c e 0
2 t o a d 0
Thank you.
(t*4)+i+1
Is an arithmetic expression. t and i are ints, the * means multiply. So for row 1, column 2, t = 1, i = 2, and nums[1][2] = 1x4+2+1 = 7.
Oh, forgot a couple things. First, the () is to specify the order of operations. So the t*4 is done first. Note that in this case the () is unnecessary, since the multiply operator takes precedence over the plus operator anyway.
Also, I couldn't tell from your question if you knew this already or not, but the meaning of rows[t][i] is array notation for accessing rows at row t and column i.
For the first part, isn't it just assigning the a value equal to the row number * 4 plus the column number? I.E. the end result of the assignment should be:
1 2 3 4
5 6 7 8
9 10 11 12
So the expression (t*4)+i+1 means "4 multiplied by the row number plus the column number plus 1". Note that the row number and column numbers in this case start from 0.
nums[t][i] is the one spot in the array it is assigning the value of (t*4)+i+1.
So if t = 1 and i = 1 then the spot num[1][1] will equal (1*4)+1+1 which is 6.
See above.
Asterisk is for multiplying.
You do what's in the ( ) first just like in any mathematical equation.
Lets see, you have
int t,i, nums[3][4];
where we reserve space for the 2d array. The values inside the array will have random values since you only reserved space.
The line :
nums[t][i] = (t*4)+i+1; //I don't understand this part/line
Assigns the values to the array. You have t and i which are loop counters, and the line (t*4)+i+1 means, take value of t, multiply with 4, plus i and plus 1.
So for t=0, i =0, you get that nums[0][0] has value (0*4) + 0 + 1 which is 1.. etc for everything else.
And ofcourse the () are just basic math parentheses.