cpointersargvstdiostrchr

Random Bytes In C Output


I just wrote my first program in C and it is a cesarean shift implementation. It works as expected with short inputs, but sometimes produces seemingly random bytes at the and of the output and I cannot figure out why.

I have tried looking at the program in GDB, but just don't have enough experience yet to figure out exactly what is going wrong. I would love to know how one would go about figuring this out with a debugger like GDB.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void rot(char*, int);

char alphabet[27] = "abcdefghijklmnopqrstuvwxyz";

int main (int argc, char* argv[]) {
    if (argc != 3) {
        printf("Usage: %s [lowercase-text] [rotation-number]\n", argv[0]);
        return 1;
    } else {
        rot(argv[1], atoi(argv[2]));
    }
}


void rot (char* t, int r) {
    char result[100];
    for (int i = 0; i < strlen(t); i++) {
        char* location = strchr(alphabet, t[i]);
        result[i] = location ? alphabet[(location - alphabet + r) % strlen(alphabet)] : t[i];
    }
    printf("%s\n", result);
}

Here is the unexpected output. The actual rotation works fine but there are some unexpected bytes at the end.

michael@linux:~/Desktop$ ./rotation 
Usage: ./rotation [lowercase-text] [rotation-number]
michael@linux:~/Desktop$ ./rotation rotations_are_cool 13
ebgngvbaf_ner_pbby��� (<- Why are these here ???)

Here was my attempt with GDB. I have not been able to identify the extra data tagging at the end. (full output @ https://pastebin.com/uhWnj17e)

(gdb) break *rot+260
Breakpoint 1 at 0x936: file ../rot.c, line 25.
(gdb) r rotations_are_cool 13
Starting program: /home/michael/Desktop/rotation rotations_are_cool 13

Breakpoint 1, 0x0000555555554936 in rot (
    t=0x7fffffffe2d2 "rotations_are_cool", r=13) at ../rot.c:25
25      printf("%s\n", result);
(gdb) x/s $rbp-0x80
0x7fffffffdde0: "ebgngvbaf_ner_pbby\377\367\377\177"

This strange occurrence only happens around 50% of the time and happens more often with longer strings. Please help explain and eliminate this. Any other tips that would improve my code are also appreciated. Thanks a dozen!


Solution

  • The end of a string is recognized by the character '\0'.

    So you could do it like this

        char result[100];
        int i;
        for (i = 0; i < strlen(t); i++) {
            char* location = strchr(alphabet, t[i]);
            result[i] = location ? alphabet[(location - alphabet + r) % strlen(alphabet)] : t[i];
        }
        result[i] = '\0';
    

    You also don't check, that result is large enough for the string, so you could allocate the needed memory dynamically

        size_t len = strlen(t)
        char *result = malloc(len + 1); /* +1 for terminating '\0' character */
        if(result == NULL) {
            /* Error allocating memory */
        }
        int i;
        for (i = 0; i < len; i++) {
            char* location = strchr(alphabet, t[i]);
            result[i] = location ? alphabet[(location - alphabet + r) % strlen(alphabet)] : t[i];
        }
        result[i] = '\0';
        printf("%s\n", result);
        free(result);