Seg Fault using strcat and strcpy

Asked

Viewed 130 times

1

This is my code:

char CodificarCesar(char *texto_nao_codificado[256], int chave){

char alf[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\n','\0'};
char mensagem_codificada[256], mensagem_original[256];

memset(mensagem_codificada,'\0',sizeof(mensagem_codificada));
memset(mensagem_original,'\0',sizeof(mensagem_original));
strcpy(mensagem_original,texto_nao_codificado);

for(int i=0;i<strlen(mensagem_original);i++)
    for(int j=0;j<strlen(alf);j++){
        if(mensagem_original[i]==alf[j]){
            mensagem_codificada[i]=alf[j+chave];
            break;
        }else if(mensagem_original[i]==toupper(alf[j])){
            mensagem_codificada[i]=toupper(alf[j+chave]);
            break;
        }else if(isspace(mensagem_original[i])){
            mensagem_codificada[i]=" ";
            break;
        }//else space
    }//for j

strcat(mensagem_codificada,"\n");
memset(mensagem_original,'\0',sizeof(mensagem_original));

return mensagem_codificada; }

I am doing a simple encryption program using César cipher, but in two situations I am receiving Segmentation faults from the beyond, apparently both cases showing that the strcat function is involved and in none of them it is even called.

Note that in situations where I get segmentation failure are situations where strings with space are input.

In the first case it is in the return of the function, after all the strings have been processed correctly.

In the second case it is in the string processing, when the Debugger arrives at the line containing some call to the strcpy function (within the equivalence if’s with some character of the alphabet).

I couldn’t find any similar case by researching, nor could I get any idea what causes or may be causing it.
Any help would be welcome.

[EDIT] Thanks @Jefferson Quesado for letting you know that I was using strcpy chars

[EDIT2] Segmentation Failure only occurs with strings with spaces

  • You make a call from strcpy to copy a single character? strcpy(mensagem_codificada[i],alf[j+chave]);?

  • Yeah, reviewing my code I was finding it weird to do mensagem_codificada[i] = alf[j+chave] and switched to `strcpy , even if it was working, to see if this was not the error, but doing so only created another error.

  • I figured the segmentation flaw came from that call, but it already existed without doing it, right?

  • Yes, it already existed, so much so that this was a solution kick that only generated a second segmentation failure separate from the first.

  • I found a possible bug/latent bug: if I pass string "zorro" with cipher key 2, which should be the result? alf[25 + 2] will point to a possible unallocated address. It may not be The mistake, but may give headache

  • Another problem, I think this more serious: alf is not a null-terminated string. It is a 27-position vector, the first 26 being lowercase letters A to Z, and the position 26 is line breaking. In addition to this position, we are at invalid address for this object. How alf is not finished null, you will have problems calling strlen(alf) and saving the princess

  • As for the first bug, this I had already noted to fix, but this problem proved more serious; as for the second, I had not even noticed it, I will fix it immediately; thank you for helping with this.

Show 2 more comments

1 answer

1


Most of the changes I made were guided by the compiler’s warnings, something we should never ignore.

I will try to quote them so that the logic that guided the amendments is clear:

Warning: Passing argument 2 of 'strcpy' from incompatible Pointer type

Referring to this line:

strcpy(mensagem_original,texto_nao_codificado);

The problem here is that the texto_nao_codificado was not declared with the right type and so the two guys do not play. texto_nao_codificado was declared as char *texto_nao_codificado[256] who’s kind char** instead of char* or char[] how was supposed.

assignment makes integer from Pointer without a cast

In this line:

mensagem_codificada[i]=" ";

If mensagem_codificada is an array of chars then each position is one char therefore cannot be assigned to a position a string and yes a char. That’s why " " should be ' '

Function Returns address of local variable

In the return:

return mensagem_codificada;

Here the compiler indicates that we are not supposed to return addresses of local variables as they are allocated in stack which is released after the function returns causing the access after the function to be invalid. Instead the variable should be allocated in the heap with malloc to persist after the function has finished,

Then the creation of this variable:

char mensagem_codificada[256];

Must become:

char* mensagem_codificada = malloc(256*sizeof(char));

Turn makes integer from Pointer without a cast

The latter has yet to do with the return and with the returned type not playing with the declaration. It is returning char* when the statement:

char CodificarCesar(char texto_nao_codificado[256], int chave){

Indicates char. Simply change the declaration to indicate char* also:

Thus:

char *CodificarCesar(char texto_nao_codificado[256], int chave){

There is yet another subtle problem that is when you swap one letter for another, here:

mensagem_codificada[i]=alf[j+chave];

One can give the case of passing the size of alf accessing an invalid memory position. For example it has the letter z and wants to move forward 5, will stay out of the array. To get around this situation you can use the operator % (module) with the size of the array to ensure that it goes around and stays inside it:

mensagem_codificada[i]=alf[(j+chave)%26];

After making all the changes the code is then like this:

char* CodificarCesar(char texto_nao_codificado[256], int chave)
{

    char alf[]= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\n','\0'};
    char mensagem_original[256];
    char* mensagem_codificada = malloc(256*sizeof(char));

    memset(mensagem_codificada,'\0',sizeof(mensagem_codificada));
    memset(mensagem_original,'\0',sizeof(mensagem_original));
    strcpy(mensagem_original,texto_nao_codificado);

    int i,j;

    for(i=0; i<strlen(mensagem_original); i++)
        for(j=0; j<strlen(alf); j++)
        {
            if(mensagem_original[i]==alf[j])
            {
                mensagem_codificada[i]=alf[(j+chave)%26];
                break;
            }
            else if(mensagem_original[i]==toupper(alf[j]))
            {
                mensagem_codificada[i]=toupper(alf[(j+chave)%26]);
                break;
            }
            else if(isspace(mensagem_original[i]))
            {
                mensagem_codificada[i]=' ';
                break;
            }//else space
        }//for j

    strcat(mensagem_codificada,"\n");
    memset(mensagem_original,'\0',sizeof(mensagem_original));

    return mensagem_codificada;
}

int main(){
    char msg_orig[] = "abc";
    printf("%s", msg_orig); //abc
    printf("\n%s",CodificarCesar(msg_orig, 2)); //cde

    return 0;
}

Watch it work on Ideone

  • Just a detail, try to encode Zorro with key 1 would return [pssp. To have the conventional circular behavior of Cezar encryption (z with key 1 maps to a), should have an additional check

  • @Jeffersonquesado Refers to the final example I gave ? Or to what came from the question?

  • To that line: mensagem_codificada[i] = mensagem_original[i]+chave ;, that you put in the issue. I did a very superficial reading of your answer, it ended up standing out

  • About the module, I believe that the size of the vector should not be 24, but 26 (27 considering the '\n', which I would not consider), since we have 26 characters. 'z' key 0 is translating to the index 25 % 24 == 1, bearing 'b'. How the key is 0, there should be no changes in value

  • 1

    @Jeffersonquesado I really appreciate the comment. Yes about the module I was now noticing that 24 was not correct. And as for the example of coding I gave is not circular, what will make sense to be to match the example of the question. I’ll adjust to that.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.