Hi,
I made a matrix with 2 rows and 3 columns, and then I try to set in row 1 column 5 a specific number. But it does not give me an error when executing the program, (which should have, because I only made 3 columns, not 5)
Your member function "set(...)" is asking for a char and the third argument but you are passing it an int from main, is that a typo from when you posted the code here? Otherwise C++ may cast it to a char in which case you should get a club.
You're not getting an error because pointers don't really have bounds checking. So almost anyplace you point them to will be a valid spot as long as you don't segfault.
This is an excellent feature of how pointers work.
buffer[1][5] clearly decompose to pointing to some memory you are permitted to write to, so it writes without problem.
When using pointers, it is up to you to ensure that the memory you are writing to is yours to write into. This is why we use proper C++ containers and that sort of thing; because buffer overrun errors and that sort of thing will never, ever go away.
Your member function "set(...)" is asking for a char and the third argument but you are passing it an int from main, is that a typo from when you posted the code here? Otherwise C++ may cast it to a char in which case you should get a club.
Yes, it was a typo, actually "test.set(1,5,'f');" is the actual code (which I altered after posting the thread lol ).
This is an excellent feature of how pointers work.
You made an array of size 2*3=6
buffer[1][5] decomposes to the element 1*5 = 5 elements from the start. Accordingly, you are writing to memory 5 elements into the matrix (which is second row, second column), which is memory you are permitted to write to, so it writes without problem.
This should work, and it does work.
I just tried with test.set(1,7,'f'); and it still works, if the array size is 6, it shouldn't be working...I mean, it COULD work, but these errors will give you 90 % of the time a segfault, which is why I find it weird the program not crashing.
and even this test.set(0,10,'f'); still works without segfault
Yes, ignore the specific number values of my original post; I wasn't paying attention properly to the exact numbers. The key point is that if you use a pointer to write into some memory, it will work if that memory is yours to write into. It doesn't matter if it's in the wrong array or you actually meant something else, and you're writing over the top of some other value you didn't mean to touch. None of that matters. Have pointer, will write! You might be writing over the top of your stack, you might be trashing something on the heap, but in general terms so long as the operating system is happy that it is your memory, you can write over it without any complaints.
If the operating system hands out huge chunks of memory to you at a time, you could be happily writing all day and not get a segfault (if you're unlucky, that is - segfaults are good).
It's what makes pointers so fantastically useful, fantastically fast, and fantastically dangerous in the wrong hands :)
The program "crashing" due to a local segfault is actually a security function of the OS. If the process tries to access a piece of memory outside of the pages that are allocated to it then the OS will kill it immediatly and give you the error you are thinking of.
Otherwise your IDE is doing some kind of checking for you, but I'm not aware of one that is capable of doing that in depth of an analysis of your code.
The default constructor for basic types does nothing.
Actually I edited the thread because I realised I was sending an INT and, since the variable is a char, it would show its char representation, it works flawlessly when I send a char.
Moschops
Yes, ignore the specific number values of my original post; I wasn't paying attention properly to the exact numbers. The key point is that if you use a pointer to write into some memory, it will work if that memory is yours to write into. It doesn't matter if it's in the wrong array or you actually meant something else, and you're writing over the top of some other value you didn't mean to touch. None of that matters. Have pointer, will write! You might be writing over the top of your stack, you might be trashing something on the heap, but in general terms so long as the operating system is happy that it is your memory, you can write over it without any complaints.
It's what makes pointers so fantastically useful, fantastically fast, and fantastically dangerous in the wrong hands :)
Yes, ignore the specific number values of my original post; I wasn't paying attention properly to the exact numbers.
What? No.
What I was pointing out was that OP's allocation strategy yields a memory layout that's completely different from what you're describing.
OP is allocating an array of pointers that point to other arrays. You're describing a compiler-allocated matrix. There are no sizes for the arrays that would make your reasoning valid.
There's no way to know whether OP was writing to memory that was his own, or to memory that the malloc() implementation used to save its own state.
Hi Helios, here was my thinking on that one (which was clobbered by not paying enough attention - such is life).
1) Create matrix consisting of two rows of size x.
2) Make pointer that seems to point to the first row, position x+(something less than x)
3) Realise that said pointer actually points to somewhere in the second row, because the memory is allocated in a big long contiguous chunk.
There are no sizes for the arrays that would make your reasoning valid.
I believe the following array sizes would make my reasoning valid:
@ helios: In the OP's origional post he had a 5 as the third argument to his function, this is the "Club" card suit when you press Alt-5 while in notepad. I guess it wasn't really useful but it would tell him that the data they get back may be exactly what they sent.
Yes, I inmediately realised after posting why it showed garbage (exactly when I read the code I pasted here)
So that part was actually ok, it would give back the data I send.
So...am I right? Shouldn't the program give a segfault? I was, at first, quite convinced that there was no flaw in this little code, but then I tried to make it "segfault" to assure it was ok, but it does seems there is a thing or two wrong coded.
3) Realise that said pointer actually points to somewhere in the second row, because the memory is allocated in a big long contiguous chunk.
No. You can't derive this from #1 and #2.
This is what could happen for height=2, width=n:
1. buffer is made to point to an array of 2 pointers:
[garbage]
[garbage]
2. buffer[0] is made to point to an array:
0x80000000
[garbage]
3. buffer[1] is made to point to an array:
0x80000000
0x00000001
If program attempts to write 1 element past the end of the first array (buffer[0][n]), it will write to *(0x80000000+n), which is almost certainly not *1.
EDIT:
Shouldn't the program give a segfault?
See my first post.
It doesn't crash (yet) because the memory at the location you wrote to happens to belong to your program. Of course, that doesn't mean that the program wouldn't crash if you let it run for long enough.
Look up "undefined behavior".
Perhaps I have been spoiled by habitual (embedded) compiler, which always makes n-dimensional arrays contiguous in memory. I acknowledge your point(s).
Only if you're doing something with memory that the operating system thinks is not yours. Presumably, you don't actually have visibility of what memory the operating system things is yours? Just because it's not part of your arrays doesn't mean it's not considered "yours" by the OS.
This is true of stack and static matrices. Not of dynamically-allocated arrays. The compiler shouldn't even have a say in the matter. It's up to malloc().
Ok, thanks to everyone ;) All cleared now (I already looked up "undefined behavior" ;) )
The problem was in my mind, thinking that the program should crash if I try to write something outbounds of its memory. Quite dangerous these pointers...