0

It's an exercise of my college. The goal is to make illegal memory store and illegal memory access and print it in char. However, using MALLOC has memory adresses doesn't store 'y', and using char x works. Why this difference? But when I use char x it shows me what I want, however, in the end show me this text "* stack smashing detected *: terminated Abortado (imagem do núcleo gravada)"

void ilegal_store(char *u)
{
    for(int i=0;i<100;i++){
        *(u+i) = 'y';
    }   
}

void ilegal_reading(char *u)
{
    for(int i=0;i<100;i++){
        printf("%d = %d\n",i,*(u+i));
    }
}

void main()
{
    //char x; WORKS
    char *x=(char *)malloc(sizeof(char)); //USING MALLOC HAS ADRESSES WHICH DOESN'T STORE THE 'y' by ilegal_store();
    if(x!=NULL){
        ilegal_store(x); //use &x when not pointer
        ilegal_reading(x); //use &x when not pointer
    }
}

  • 2
    What do you mean saying "does not work"? The code has undefined behavior provided that you are accessing memory beyond the array. – Vlad from Moscow Aug 29 '19 at 14:29
  • Ok, thanks. I know this and I want this illegal access for better understanding of C. And it works if I use (printf("\n%d = %c", *(p+i), *(p+i)) – Brendon Peres Aug 29 '19 at 14:40
  • 1
    Assuming no UB, `printf` is buffering its output (and may only flush it when printing a newline). Try adding a `fflush(stdout)` after the `printf`. –  Aug 29 '19 at 14:41
  • 1
    "Does not work" is not a very useful description of your problem. Please always include what output you expect, what output you get and what input you provide. What does your program do in cases when it "does not work"? – Gerhardh Aug 29 '19 at 15:05
  • @BrendonRusPeres If we haven't driven you away yet, do try mosvy's suggestion and add an `fflush(stdout)` after your printf with `%c`. There's a pretty good chance that's the issue here. – Steve Summit Aug 29 '19 at 15:14
  • So sorry guys, I am newbie in forum... I edited my ask, now it has good description. Could you still help me? – Brendon Peres Aug 30 '19 at 01:50

1 Answers1

3

The C standard does not permit you to dereference a pointer to memory that you don't own. The behaviour on attempting to do so is undefined. Undefined behaviour manifests itself in many curiosities such as "working" sometimes, not "working" sometimes, or the compiler even erasing that particular branch: it's allowed to assume that undefined behaviour does not occur.

It's possible that you will not get a crash at exactly the first undefined dereference. Because the output of printf is frequently buffered and therefore often in lag of the code generating the output, you might be able to produce a extra output for the uncommented case by flushing the buffer after every iteration using fflush(stdout). The presence of the newline character in the case you cite as working can also flush the buffer. It's probably the newline character that is producing the different behaviour.

Finally, however this is dressed up, you are circumventing contraints the language places on you. If you want to circumvent these constraints then you need to use a different language. Many C compilers support inline assembly. That's what you need to use in this instance.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • All very true, but this doesn't answer the question. – Steve Summit Aug 29 '19 at 15:02
  • He's discovered that he *can* access and print the memory -- or at least some of it -- using `"%d %c \n"`. He's wondering why he gets no output at all when he uses `"%c"`. I suspect the answer is as suggested by @mosvy 's comment. – Steve Summit Aug 29 '19 at 15:05
  • 1
    Look, I can wield the "it's UB so don't think about it" hammer as well as the next guy, but at some point, senselessly bludgeoning questioners with it is not helpful, and this is one of those cases. Your answer completely fails to even address (never mind answer) the main thrust of the OP's question. – Steve Summit Aug 29 '19 at 15:10
  • @SteveSummit: On that we'll have to disagree. For me "The goal is to make illegal memory access and print it in char. " is the important bit. It's not possible. I've given plenty of answers analysing UB, this one being my most recent https://stackoverflow.com/questions/57628986/why-doesnt-d-d-throw-a-division-by-zero-exception-when-d-0/57629065#57629065 – Bathsheba Aug 29 '19 at 15:12
  • For the record, I also disagree with "you need to use inline assembly", but the little robot is warning me about extended discussion and asking if I want to move this to chat, but I don't, so I'll stop now. – Steve Summit Aug 29 '19 at 15:12
  • Comments are enough for me, I wasn't planning to answer, but thanks. Two of mine: [here](https://stackoverflow.com/questions/57543936/why-does-a-2d-array-get-changed-on-copying-one-of-its-rows-to-a-previously-undef/57544568#57544568) and [here](https://stackoverflow.com/questions/57645610/minimum-length-of-string-that-can-crash-some-application/57645826#57645826). Note I got *downvoted* on the second one, because the upvoted answerers there insisted on analyzing the undefined behavior. Go figure. (But I think we're on the same page. HAND, and all that. :-) ) – Steve Summit Aug 29 '19 at 15:24
  • @SteveSummit I've put an explanatory paragraph in, at some risk to the anti-UB-analysis-police. – Bathsheba Aug 29 '19 at 15:26
  • Thanks everybody. My problem is not more with printing, but store. Sorry I'm newbie in forum. Could you help me, I'll be grateful. – Brendon Peres Aug 30 '19 at 02:08