找不到细分错误

时间:2020-03-05 13:31:25

标签: c

我正在做我的学校项目,最近我一直在努力寻找代码中的细分错误。您能帮我检查一下代码吗?输入的是“ Hello world!”该函数应将每个字符转换为位。最后的a变量仅用于检查我是否可以打印它(我不能)。谢谢

unsigned char* bit_encrypt(const char* text){
  char text_copy[strlen(text)];
  printf("Strlen: %ld\n", strlen(text));
  bool bits[strlen(text_copy)][8];
  int dec = 0;
  int j = 0;

  for(int i = 0; i < strlen(text); i++){
    text_copy[i] = text[i];
    dec = (int)text_copy[i];

      if(dec >= 128){
        bits[i][j] = true;
        dec = dec - 128;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 64){
        bits[i][j] = true;
        dec = dec - 64;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 32){
        bits[i][j] = true;
        dec = dec - 32;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 16){
        bits[i][j] = true;
        dec = dec - 16;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 8){
        bits[i][j] = true;
        dec = dec - 8;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 4){
        bits[i][j] = true;
        dec = dec - 4;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec >= 2){
        bits[i][j] = true;
        dec = dec - 2;
      }
      else{
        bits[i][j] = false;
      }
      j++;

      if(dec == 1){
        bits[i][j] = true;
        dec = dec - 1;
      }
      else{
        bits[i][j] = false;
      }
      dec = 0;
      j = 0;
  }
  text_copy[strlen(text)] = '\0';

  for(int i = 0; i < strlen(text_copy); i++){
    printf("%c:  ", text_copy[i]); 
    for(int j = 0; j < 8; j++){
      printf("%d ", bits[i][j]);
    }
    printf("\n");
  }
  int a = 53;
  printf("%d", a);




 /* unsigned char* vystup = (unsigned char*)calloc(strlen(text_copy), sizeof(unsigned char*));
*/

  return 0;
}

输出是:

Strlen: 12
H:  0 1 0 0 1 0 0 0
e:  0 1 1 0 0 1 0 1
l:  0 1 1 0 1 1 0 0
l:  0 1 1 0 1 1 0 0
o:  0 1 1 0 1 1 1 1
 :  0 0 1 0 0 0 0 0
w:  0 1 1 1 0 1 1 1
o:  0 1 1 0 1 1 1 1
r:  0 1 1 1 0 0 1 0
l:  0 1 1 0 1 1 0 0
d:  0 1 1 0 0 1 0 0
!:  0 0 1 0 0 0 0 1
Segmentation fault

2 个答案:

答案 0 :(得分:1)

声明数组char text_copy[strlen(text)]时不会初始化其中的值。此时,它已填充垃圾。
然后,您尝试从中获取字符串的长度。 bool bits[strlen(text_copy)][8]strlen一直在计算字符数,直到找到'/ 0'。因此,您得到的字符串长度错误,并且数组bits[]的大小错误。
开始使用值填充bits[]时,您使用的是text而不是text_copy的长度。 C编译器允许您覆盖bits[]之后的值,并且其他变量中的某些数据会损坏。
在编程的某个时刻,您尝试访问的存储数据超出bits[]的大小,这可能会导致分段错误。

如果将bool bits[strlen(text_copy)][8];更改为bool bits[strlen(text)][8];,程序将按预期执行。

答案 1 :(得分:0)

请注意,您正在做什么,即加扰

只需验证您的输入并初始化变量即可消除大多数(不是全部)问题:

unsigned char* bit_encrypt(const char* text)
{
    int len = 0;
    //validate input:
    if(!text) return NULL;
    if((len = strlen(text)) == 0) return NULL;//capture length using strlen once, leave if 0
    char text_copy[len+1]; //+1 for termination char , uninitialized
    memset(text_copy, 0, sizeof(text_copy));//initialized  
    printf("Strlen: %ld\n", len);
    bool bits[len][8]; //uninitialized
    memset(bits, 0, sizeof(bits));//initialized
    int dec = 0;
    int j = 0;

然后,在底部进行以下更改是可选的,但要避免在循环中调用`strlen,请获取一次长度,然后在循环中使用它:

循环后修改代码:

....
}
text_copy[len] = '\0';
len = strlen(text_copy);//again, get length once to avoid calling it in loop
for(int i = 0; i < len; i++){
    printf("%c:  ", text_copy[i]); 
    for(int j = 0; j < 8; j++){
        printf("%d ", bits[i][j]);
    }
    printf("\n");
}
int a = 53;
printf("%d", a);

这些更改导致相同的输出,但没有例外:

enter image description here

EDIT 解决评论中的问题:
以下代码创建了bool **scramblestrlen("Hello World!")行和8列,但是它是动态完成的,然后在完成时释放。 这是在评论中解决您的问题:
_但仍然出现细分错误。 Printf(“%d”,a)被忽略。可能是因为返回0了吗?并且具有main:加密的未签名char *;加密= bit_encrypt(“ Hello world!”); printf(“%s \ n”,已加密); ?? _。
您的原始帖子中没有包含main(),所以我无法回答您为什么出现 seg-fault 的问题。但是,我包括了int main(void){...},所以我可以说明一种在没有 seg-fault 的情况下返回数据的方法。这是我完整的代码:

    bool  **bit_encrypt(const char* text);
    bool ** Create2D(int c, int r);
    void free2D(bool **arr, int c);

    int main(void)
    {
        bool **scambled = bit_encrypt("Hello World!");
        //scrabled is not a 2D arranged set of bits, 8 wide with strlen("Hello World!") long
        free2D(scambled, strlen("Hello World!"));
        return 0;
    }
    bool **bit_encrypt(const char* text)
    {
        int len = 0;
        //validate input:
        if(!text) return NULL;
        if((len = strlen(text)) == 0) return NULL;//capture length using strlen once, leave if 0
        char text_copy[len+1]; //+1 - room for null
        memset(text_copy, 0, len+1);//initialized  
        printf("Strlen: %ld\n", len);
        bool **bits = Create2D(len, 8); //uninitialized, changed from bool to match return of prototype
        if(!bits) return NULL;
        int dec = 0;
        int j = 0;

        for(int i = 0; i < len; i++){
            text_copy[i] = text[i];
            dec = (int)text_copy[i];

            if(dec >= 128){
                    bits[i][j] = true;
                    dec = dec - 128;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 64){
                bits[i][j] = true;
                dec = dec - 64;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 32){
                bits[i][j] = true;
                dec = dec - 32;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 16){
                bits[i][j] = true;
                dec = dec - 16;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 8){
            bits[i][j] = true;
                dec = dec - 8;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 4){
                bits[i][j] = true;
                dec = dec - 4;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec >= 2){
                bits[i][j] = true;
                dec = dec - 2;
            }
            else{
                bits[i][j] = false;
            }
            j++;

            if(dec == 1){
                bits[i][j] = true;
                dec = dec - 1;
            }
            else{
                bits[i][j] = false;
            }
            dec = 0;
            j = 0;
        }
        text_copy[len] = '\0';
        len = strlen(text_copy);//again, get length once to avoid calling it in loop
        for(int i = 0; i < len; i++){
            printf("%c:  ", text_copy[i]); 
            for(int j = 0; j < 8; j++){
                printf("%d ", bits[i][j]);
            }
            printf("\n");
        }
        int a = 53;
        printf("%d", a);

        return bits;
    }

    bool ** Create2D(int c, int r)
    {   
        bool **arr;
        int    y;

        arr   = calloc(c, sizeof(bool *));
        for(y=0;y<c;y++)
        {
            arr[y] = calloc(r, sizeof(bool));  
        }
        return arr;
    }

    void free2D(bool **arr, int c)
    {
        int i;
        for(i=0;i<c;i++)
        {
            free(arr[i]);
        }
        free(arr);
    }