0

I was curious to know why the following code snippet works in some C compilers and not others. My professor can compile this code in DevC++ and so can I, but I can not compile this code in VS 2010. Any ideas? VS says a.word has a bad pointer. I assume VS is mad because I haven't initialized a.word, but why does the code compile and work in DevC++? I have to add a.word=""; before the strcpy and then it works in VS, but again I am curious to know why. Thanks

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foo{  int num;
             char* word;
             struct foo *ptr;};
int main() {
        struct foo a;
        a.num = 5; a.ptr = &a;
        strcpy(a.word,"whichword");
}
John R
  • 350
  • 2
  • 5
  • 19
  • Indeterminate pointers are the bane of most buggy C-code existence. I suggest you provide some *memory* for that `strcpy()` to use as a destination. As written, you've provided no such thing. – WhozCraig Apr 19 '13 at 17:52
  • VS is not mad at all. Even if you add `a.word = ""` it can still fail with some compiler configurations. – Yakov Galka Apr 19 '13 at 17:52
  • @ybungalobill Jam up your warnings to include implicit constant coercion and it will complain loud enough, especially if you compile with warnings as errors. – WhozCraig Apr 19 '13 at 17:54
  • 1
    "I have to add `a.word=""`" - if you replace the strcpy with this then the program's legal and has defined behaviour. If you mean that you added `a.word=""` before the `strcpy` then the program's still broken: you shouldn't write over a string literal. You need to create some writeable memory into which *whichword* can legally be copied - e.g. a character array or malloced buffer. – Tony Delroy Apr 19 '13 at 18:27
  • Different compilers have different default warning levels, and some compilers conform to the standard better than others. It's not uncommon for one compiler to reject code that another accepts, at least with default warning levels turned on. – John Bode Apr 19 '13 at 20:43

1 Answers1

6

a.word is an unitialized pointer (char*) not an uninitialized string (char[n]). This is quite different:

char buf[20];  /* Uninitialized string, backed by memory, */
char* s;       /* but an unitialized `char*` is pointing to some random */
               /* memory address. */
               /* Any attempt to access it is undefined behaviour. */

I have to add a.word=""; before the strcpy and then it works in VS

This would also result in undefined behaviour as a.word is pointing at a string literal which is not permitted to be modified.

The only two solutions are to change word to be a fixed sized array or to dynamically allocate memory for word before copying. In either case the memory associated with word must be large enough to store the string being copied (plus the null terminating character).

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • +1 for the good answer, but especially for the *access* descriptor. Most people would just say "write". It is, in fact, undefined behavior to even *evaluate* it. – WhozCraig Apr 19 '13 at 17:55