I tried to compile the follow sample code:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main ()
{
if (strlen <= 0) {
cout << "trace1" << endl;
return 0;
}
cout << "trace2" << endl;
return 0;
}
The strange thing is that it compiles successfully. Do you have any idea why?
I have not declare the strlen as variable.
Using just the identifier of a function decays to a function pointer of the corresponding type. In this case, strlen is a pointer of the type size_t (*)(const char *). This pointer holds the address of the first instruction of the function in the executable code.
Testing the value of that pointer is legal, whatever the reason may be, although it seems strange in the code fragment you have provided.
strlen without the () gives you a function pointer to the address where the strlen function is allocated in memory.
The program prints "trace1" if the library function strlen is allocated at an address less than 0, which is impossible on every computer in the world, or if it is allocated at address 0 (extremely unlikely but possible). Otherwise, if strlen is allocated at an address that is larger than zero (most likely the case), it prints "trace2".
It's probably decays into an address which decays into an integer. A real compiler will probably fill the screen with warnings.
If you do the same with other functions than strlen, this sample code will print trace2 because strlen is a pointer to function size_t strlen ( const char * str ) and it's value should be a positive number.
cout << (size_t *) strlen << endl;
cout << (size_t *) strcat << endl;
for example the code above prints:
0x7fff84d29110
0x7fff84d63953
on my machine (as you see these are positive numbers because they are started with 7).
Also if I print strlen and strcat without casting to (size_t *) the result will be 1 which means that these functions are valid.
Related
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number = 900;
cout << std::string("Hello, World!" + number) << std::endl;
return 0;
}
I know the correct solution will be to use std::to_string(number). But the question here is, why do I not get a segmentation fault? I even ran it through valgrind. The string length is around 13 and I move the pointer 900.
The expression "Hello, World!" + number is a const char[] literal added to an int. The former decays to a const char* pointer and you add number to it by pointer arithmetic.
Since that final pointer is not in the original string constant, you are passing an invalid const char* pointer to a std::string constructor, and the behaviour of your program is undefined. Anything can happen at that point, including a runtime crash. An aggressively optimising compiler might omit the undefined expression altogether; that's getting progressively more common.
Boom!
If you wanted to concatenate 900 to the string, then you could have written
std::cout << std::string("Hello, World!" + std::to_string(number)) << std::endl;
Not really sure what's going on here, I'm using Clion as my IDE which I don't believe has anything to do with this but I figured I'd add that information. My confusion comes from a function that I wrote
int Arry()
{
int Mynumbers [5] = {10};
std::cout << Mynumbers;
}
something simple. It should be assigning 5 integers the value of 10. But when I print out Mynumbers I am shown the memory address. Why is this happening, I thought that was what calling pointers was for. Thank you for your time.
Sincerely,
Nicholas
It is a bit complicated, and there are a few issues at play:
std::cout (actually, std::ostream, of which std::cout is an instance, does not have an overload of operator<< that understands plain arrays. It does have overloads that understand pointers.
In C++ (and C) an array name can be used as an expression in a place where a pointer is needed. When there is no better option, the array name will decay to a pointer. That is what makes the following legal: int a[10] = {}; int* p = a;.
The overload that takes a pointer prints it as a hexadecimal address, unless the pointer is of type char* or const char* (or wchar versions), in which case it treats it as a null terminated string.
This is what is happening here: because there isn't an operator<< overload that matches the array, it decays to the overload taking a pointer. And as it isn't a character type pointer, you see the hexadecimal address. You are seeing the equivalent of cout << &MyNumbers[0];.
Some notes:
void Arry() // use void if nothing is being returned
{
int Mynumbers[5] = {10}; // first element is 10, the rest are 0
//std::cout << Mynumbers; // will print the first address because the array decays to a pointer which is then printed
for (auto i : Mynumbers) // range-for takes note of the size of the array (no decay)
std::cout << i << '\t';
}
In C++, you can think of an array as a pointer to a memory address (this isn't strictly true, and others can explain the subtle differences). When you are calling cout on your array name, you are asking for it's contents: the memory address.
If you wish to see what's in the array, you can use a simple for loop:
for (int i = 0; i < 5; i++)
std::cout << Mynumbers[i] << " ";
The value of Mynumbers is in fact the adress of the first element in the array.
try the following:
for(int i=0; i<5;i++) {
cout << Mynumbers[i];
}
I need to use an array of strings with an unknown size. Here I have an example to see if all works fine. I need to know that array's size in ClassC but without passing that value as an argument. I've see so many ways to do it (here and in google) but as you will see now, they didn't work. They return the number of chars in the first position of the array.
void ClassB::SetValue()
{
std::string *str;
str = new std::string[2]; // I set 2 to do this example, lately it will be a value from another place
str[0] ="hello" ;
str[1] = "how are you";
var->setStr(str);
}
Now, in ClassC if I debug, strdesc[0] ="hello" and strdesc[1] = "how are you", so I suppose that class C is getting the info ok....
void classC::setStr(const std::string strdesc[])
{
int a = strdesc->size(); // Returns 5
int c = sizeof(strdesc)/sizeof(strdesc[0]); // Returns 1 because each sizeof returns 5
int b=strdesc[0].size(); // returns 5
std::wstring *descriptions = new std::wstring[?];
}
So.. in classC, how can I know strdesc's array size, that should return 2?? I have also tried with:
int i = 0;
while(!strdesc[i].empty()) ++i;
but after i=2 the program crashes with a segmentation fault.
Thanks,
Edit with the possibles SOLUTIONS:
Conclusion: There is no way to know the array's size once I pass its pointer to another function
Pass the size to that function... or...
Use vectors with std::vector class.
how can I know strdesc's array size
You cannot know the size of an array from a pointer to that array.
What you can do is pass the size as another parameter. Or even better, use a vector instead.
but after i=2 the program crashes with a segmentation fault.
Accessing beyond the array boundary has undefined behaviour.
With this Kind of code you will get memory leaks and other kind of C-style problems.
use vector:
#include <vector>
#include <string>
#include <iostream>
...
std::vector<std::string> my_strings;
my_strings.push_back("Hello");
my_strings.push_back("World");
std::cout << "I got "<< my_strings.size() << " strings." << std::endl;
for (auto& c : my_strings)
std::cout << c << std::endl;
An Example demonstrating Passing an array as argument
#include <iostream>
#include <malloc.h>
using namespace std;
typedef unsigned char U8;
#define MAX_LEN 20
void func1(U8* arr)
{
printf(" Passing Base address Element1 = %s\n",arr);
}
void func2(U8* arr)
{
printf(" Passing Pointer address Element1 = %s \n",arr);
}
int main()
{
U8 arr[MAX_LEN] = "Stack Overflow\n";
U8* arr1 = (U8*)malloc(sizeof(MAX_LEN));
func1(arr); /* Passing Base address */
memcpy(arr1,arr,sizeof(arr));
/*
memcpy(arr1,arr,sizeof(MAX_LEN)); Leads to Heap Corruption why ?
*/
func2(arr1);/* Passing pointer */
free(arr1);
cout << "Array Freed" << endl;
cin.get();
return 0;
}
Queries :
1. which is the best Practise in consideration with data Processing.[data on stack or Heap]
2. Please suggest reliable methodology to be used for such cases
memcpy(arr1,arr,sizeof(MAX_LEN)); // Leads to Heap Corruption why ?
Because sizeof(MAX_LEN) is equivalent to sizeof(20) which is equivalent to sizeof(int).
This means you'll copy 4 or 8 bytes (depending on your platform). In fun1 you then print the array as if it were a null terminated string. There is no null terminator though, since you didn't copy it and printf happily runs out of bounds.
sizeof(arr), on the other hand, gives you correct size of 20.
sizeof operator queries the size of the type of the expression you give it as operand, not the value. It's purely compile time operator. The type of integer literal 20 is int and it'll return the size of that type.
Honestly? If you write in C++, simply use std::vector, pass it by reference and forget about the whole problem.
If you really have to use C-style arrays, I'd say, that in most cases (I mean, 99.9%), you'll have to allocate the array on the heap, because programs usually have limited stack memory available and placing an array there is generally not a good idea.
Remember though, that constant text expressions defined in the following way:
const char * myText = "Alice has a cat";
may not be stored on the stack, but somewhere (depending on C++ compiler). These won't occupy place on the stack and mostly probably this is the case in your example. In this example, a pointer to that text is stored on the stack, but the text itself is (mostly probably) stored elsewhere.
char c='c';
char *pc = &c;
char a[]="123456789";
char *p = &(a[1]);
cout <<"the size of the a: "<< sizeof (a)<< endl; //10
cout <<"the size of the p: "<< sizeof (p)<< endl; //4
cout << p[100] <<endl;//cross boundary intentionally
cout << pc[0];//c
cout << pc[1];
Compiler no longer treat the p as an array? how does compiler verify whether it is or not an Array? Is there any difference between p and pc ?
Thanks!!!!
Compiler no longer treat the p as an array?
It never treated it as an array, because it was not. It was always a pointer. Arrays are not pointers. Read this, accept it, embrace it! They sometimes decay into pointers (when passed as parameters), but they are not pointers.
Is there any difference between p and pc ?
Type-wise - no. There's a difference in that they point to different chars.
Also, pc[1] is undefined behavior. You only own the memory pc points to directly - i.e. a single byte that contains the character 'c'. Same goes for p[100].
The compiler treats as arrays only variables declared as arrays, i.e. with square brackets. Pointers are not arrays, though, although you can treat array names as if they were pointers for the purposes of constructing pointer expressions.
If you would like to use an array structure where the compiler checks the bounds of the array, you can use std::vector. For example
#include <vector>
int main()
{
int array[]={0,1,2,3,4,5};
std::vector<int> vec;
vec.assign(array, array+6);
for(unsigned int i=0; i<vec.size(); ++i)
{
std::cout << vec.at(i);
}
return 0;
}
Here, vec.at(i) checks the bounds of the vector. If you use vec[i], this is also valid but the compiler does not check the bounds. Hope that helps.
The compiler cannot and will not treat p as an array. p is just a pointer to a char to which any address can be assigned. Why would the compiler treat it as an array?