Hi, this is a code for Simple Console based text editor from Complete Reference to C++ by Herbert Shildt:

#include "stdafx.h"
#include "conio.h"

#define MAX 5
#define LEN 20
char text[MAX][LEN];

int _tmain(int argc, _TCHAR* argv[])
{
	register int t, i, j;
	printf("Enter an empty line to quit.\n");

	for(t=0; t<MAX; t++) 
	{
		printf("%d: ", t);
		gets(&text[t][0]);
		if(!*text[t]) break; /* directly hiting Enter key appends '\0' i.e. null, hence &text[t] will be null;  quit on blank line */  
	}
	for(i=0; i<t; i++) 
	{
		for(j=0; text[i][j]; j++)
			putchar(text[i][j]);
		putchar('\n');
	}

	getch();
	return 0;
}

I insert a letter 'a' 20 times on first line:
[image:http://img40.imageshack.us/f/52134015.png/]

& then 'b' 20 times:
{image: http://img59.imageshack.us/i/29952735.png/}

but at first, it stores 'a' correctly:
{image: http://img141.imageshack.us/i/79038161.png/}

however for second iteration, it stores the 'b's incorrectly:
[image: http://img689.imageshack.us/i/80327231.png/]

this continues further, if I enter 'c' 20 times & so on.

The final output is also wrong:
[image: http://img3.imageshack.us/i/49207766.png/]

However the code works great for small strings:
[image: http://img822.imageshack.us/i/31994060.png/]
Why is this overlapping?

Please help.

Dani AI

Generated

As already pointed out, the weird output is not a mystery of the compiler — it’s a classic out‑of‑bounds write on your 2‑D char array. The rows of text[MAX][LEN] are stored contiguously in memory, so if an input needs more bytes (including the terminating '\0') than a single row provides, it will overwrite the next row’s bytes and/or its terminator. That produces the garbled second/third lines you saw.

Think of the buffer as a flat sequence of bytes:

[text[0][0] ... text[0][19]] [text[1][0] ... text[1][19]] ...
       row 0 (20 bytes)            row 1 (20 bytes)

If you type 20 characters into a 20‑byte row there’s no room for the '\0', so the '\0' (or the extra input) lands in the next row and corrupts it. The result is undefined and will vary.

Practical fixes:

  • Minimal C fix: replace gets with fgets and strip the trailing newline; if the read fills the buffer, discard the rest of that input line to avoid leftover characters.
    if (fgets(text[t], LEN, stdin)) {
    size_t n = strlen(text[t]);
    if (n && text[t][n-1] == '\n') text[t][n-1] = '\0';
    else { int c; while ((c = getchar()) != '\n' && c != EOF); }
    }
  • Best C++ fix: use std::string and std::getline (or a std::vector<std::string>) so you aren’t manually managing buffer sizes.

Debugging tips: print the row addresses (printf("row %d @ %p\n", t, (void*)&text[t][0])) or watch the memory in Visual Studio to see how bytes are overwritten. Run-time checks and prefer STL containers or bounded reads — undefined behavior from buffer overruns is the real culprit, not VS2010 or Windows.

Your array has 20 columns. When you use puts to read a string, it puts a null character ('\0') at the end of its input. So if your input is 19 characters or longer, the input (including the null character) runs off the end of the row of the array and onto the next row.

So this program fails any time it gets more than 19 characters of input.

More generally, this failure is an unavoidable aspect of using gets: The gets function takes a pointer to memory, and simply overwrites as much memory as necessary to hold its input. Because you don't know how much input you're going to get, you don't know how much memory it is going to overwrite.

As a consequence of this behavior, you should never use gets in your programs for any reason. Because it overwrites memory unpredictably, any program that uses gets has security problems that are impossible to fix. For that reason, I think that if you are using a book that recommends the use of gets, you should consider using a different book.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.