strings out of bounds - overflow

This was the original code
int main(void)
{
char hello[] = "hello ", world[] = "world!\n", *s;
s = strcat(hello,world);
printf(s);
return 0;
}
char hello[] = "hello ", world[] = "world!\n", *s;
strcat(hello,world);
printf(hello);
i changed it to what it is below
i am positive i fixed that code, but my instructor marked me off.
like i told him it doesn't even use the pointer, so this is fine. he said he doesn't think it's correct
am i wrong?
like i ran it 50 times and it still works.

Your instructor is correct. hello is only big enough to hold 6 characters (plus a null-terminator). So trying to strcat something into it writes past the end, causing undefined behaviour.

Related

Why this is an infinite loop

i have declared a map below using stl and inserted some values in it.
#include<bits/stdc++.h>
int main()
{
map<int,int> m;
m[1]=1;
m[2]=1;
m[3]=1;
m[4]=1;
m[5]=1;
m[6]=1;
for(auto it=m.begin();it!=m.end();)
{
cout<<it->first<<" "<<it->second<<endl;
it=it++;
}
return 0;
}
When i executed the above written code it ended up in an infinite loop. Can someone tell me why it does so?
I am incrementing the value of iterator it and then it gets stored in it which should get incremented next time the loop is executed and eventually it should terminate normally.Am i wrong?
The bad line is it = it++;. It is undefined behavior! Because it is not defined, when it is increased, in your case it is increased before the assingment to itsself again, that the value of it before it is increased is assigned to it again and so it keeps at the first position. The correct line would be it = ++it; or only ++it;/it++;, because it changes itsself.
Edit
That is only undefined with the builtin types, but in here that is defined by the source-code of the map in the stl.
If you try doing something similar with an int, you'll get a warning:
int nums[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof nums / sizeof *nums; ) {
cout << nums[i] << '\n';
i = i++;
}
warning: operation on 'i' may be undefined [-Wsequence-point]
However, when you're using a class (std::map::iterator) which has operator overloading, the compiler probably isn't smart enought to detect this.
In other words, what you're doing is a sequence point violation, so the behavior is undefined behavior.
The post-increment operation would behave like this:
iterator operator ++ (int) {
auto copy = *this;
++*this;
return copy;
}
So, what happens to your increment step is that iterator it would get overwritten by the copy of its original value. If the map isn't empty, your loop would remain stuck on the first element.

Extract trailing int from string containing other characters

I have a problem in regards of extracting signed int from string in c++.
Assuming that i have a string of images1234, how can i extract the 1234 from the string without knowing the position of the last non numeric character in C++.
FYI, i have try stringstream as well as lexical_cast as suggested by others through the post but stringstream returns 0 while lexical_cast stopped working.
int main()
{
string virtuallive("Images1234");
//stringstream output(virtuallive.c_str());
//int i = stoi(virtuallive);
//stringstream output(virtuallive);
int i;
i = boost::lexical_cast<int>(virtuallive.c_str());
//output >> i;
cout << i << endl;
return 0;
}
How can i extract the 1234 from the string without knowing the position of the last non numeric character in C++?
You can't. But the position is not hard to find:
auto last_non_numeric = input.find_last_not_of("1234567890");
char* endp = &input[0];
if (last_non_numeric != std::string::npos)
endp += last_non_numeric + 1;
if (*endp) { /* FAILURE, no number on the end */ }
auto i = strtol(endp, &endp, 10);
if (*endp) {/* weird FAILURE, maybe the number was really HUGE and couldn't convert */}
Another possibility would be to put the string into a stringstream, then read the number from the stream (after imbuing the stream with a locale that classifies everything except digits as white space).
// First the desired facet:
struct digits_only: std::ctype<char> {
digits_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
// everything is white-space:
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
// except digits, which are digits
std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
// and '.', which we'll call punctuation:
rc['.'] = std::ctype_base::punct;
return &rc[0];
}
};
Then the code to read the data:
std::istringstream virtuallive("Images1234");
virtuallive.imbue(locale(locale(), new digits_only);
int number;
// Since we classify the letters as white space, the stream will ignore them.
// We can just read the number as if nothing else were there:
virtuallive >> number;
This technique is useful primarily when the stream contains a substantial amount of data, and you want all the data in that stream to be interpreted in the same way (e.g., only read numbers, regardless of what else it might contain).

xcode Assertion failed

On build of a project I am getting an Assertion failed pointing at this code. Any ideas why please? I have tried a cleaning, deleting derived data, closing xcode and more. Any help please.
unsigned int
FNVForCString(
const char* s)
{
assert(s);
unsigned int hash = 2166136261;
int ch;
while (0 != (ch = *s++))
{
hash *= 16777619;
hash ^= ch;
}
return hash;
}
Just going to say it is failing on the assert(s); line.
Is the language C? I've made that assumption here, though the answer varies very little if this is Objective-C.
The value you pass into the function is NULL
The assert is there to say "If the value s is NULL, fail at this point.

Help needed with F_NOCACHE in mac

I am Srinivasa Raghavan and new to this group.
I am facing problem with non caching the file.
the code looks like the below:
main()
{
int fd;
char buf[512] = {'\0'};
fd = fopen("Sample.bin",O_RDONLY);
fcntl(fd, F_NOCACHE, 1);
fcntl(fd, F_RDAHEAD, 1);
read(fd, buf, sizeof(buf));
close(fd);
if(buf[0] == 'x' )
print("non-cached\n");
else
printf("cached\n")
}
the problem was, the F_NOCACHE doesn't not work properly, and all the time I get the message cached only. The firware will always update the value 'x' in sample.bin.
the above code works if I put the entire stuff (open, fcntl, read and close) in an indefinite loop (take long time to come out) like the below.
main()
{
while(1)
{
open...
fcntl(.., F_NOCACHE)
read(....
close..
if(buf[0] == 'x')
break;
}
}
I am really stuck with this for a week time, I want to know the exact behaviour of F_NOCACHE, and any information will be highly appreciated.
Thanks in advance,
Srinivasa Raghavan
That's not what it's for. F_NOCACHE tells the system that you don't expect to read that data* off the disk again any time soon, so it shouldn't bother caching it.
*Yes, "data" is plural, I know.

How to solve access violation writing location error?

I have a simple program and I get access violation at *(str + start). Why? I should be able to change it. Right?
void fn()
{
char *str = "Hello wordl!";
int end = strlen(str);
int start = 0;
end--;
while(start < end)
{
*(str + start) = *(str + end); <--- Access violation writing location *(str + Start).
end--;
start++;
}
}
char *str = "Hello World"; is a const string, and cannot be modified. The compiler is free to put it into a non-writable location, resulting in the crash you see.
Replacing the declaration with char str[] = "Hello World"; should do what you want, putting the string into a modifiable array on the stack.
No, you should not. "Hello world" is a constant string literal, you need to allocate memory using malloc() in C, or new in C++ if you want memory you are free to modify.
As others have pointed out, literal strings may be stored in a read-only area of memory. Are you compiling with warnings turned on? You should get a warning about discarding the constness of the string literal.
What you can do instead is:
char *str = strdup("Hello, world!");
// Modify the string however you want
free(str);
It's because you're writing to a string literal's storage, which may be in a protected area of memory.
In your example, Hello wordl! is constant string, any attempt to modify this constant string will result in an exception.
Instead, You can do this -
string s = "Hello wordl!";
char* ptr = &s[0];
and then play around with ptr.

Resources