获取字符串切片时出现未知字符然后出现段错误

问题描述 投票:0回答:1

我遇到了一个非常奇怪的问题。我相信这与字符串切片有关,但我什至很难找到我的错误。

我的代码如下:

char * readSlice (char * buf, int pos, int len) {
    char * str = malloc(len);
    memcpy(str, buf + pos, len);
    return str;
}

void writeSlice (char * str, char * buf, int pos, int len) {
    memcpy(buf + pos, str, len);
    free(str);
}

char * intToStr (int i, int l) {
    char * s = malloc(l);
    for (int j = 0; j < l; j++) {
        *(s + j) = (i / pow(10, l - j - 1)) + '0';
        i = i % (int) pow(10, l - j - 1);
    }
    return s;
}

int strToInt (char * s, int l) {
    printf("%s\n", s);
    int i = 0;
    for (int j = 0; j < l; j++) {
        i += (*(s + j) - '0') * pow(10, l - j - 1);
    }
    free(s);
    return i;
}

void ReadString (char * s) {
    struct MyS * n = malloc (sizeof n);
    n->first = strToInt(readSlice(s, 0, 4), 4);
    for (int i = 1; i < 16; i++) {
        printf("%d\n", i);
        (n->other)[i] = strToInt(readSlice(s, i * 4, 4), 4);
    }
}

int main () {
    ReadString("0000000100020003000400050006000700080009001000110012001300140015");
}

此代码应该打印出来

0000
1
0001
2

...

15
0015

但是,它打印出来了

0000
1
0001[?]
2
0002[?]

...

6
0006[?]
Segmentation Fault

其中 [?] 是单个字符。

但是,当我删除所有对 free() 的调用时,它工作得很好(减去泄漏)。

我不知道我做错了什么......

c segmentation-fault
1个回答
0
投票
  1. 通过malloc分配数组的模式是:

    sturct MyS *s = malloc(sizeof *s);
    

    您只为指针分配了空间(大概是 8 个字节)。

  2. readSlice()
    不返回
    \0
    终止的字符串,这使得
    printf()
    调用
    strToInt()
    未定义的行为。我只会
    strndup()
    readSlice()
    :

    char *readSlice (char *buf, int pos, int len) {
        return strndup(buf + pos, len);
    }
    
    
  3. 缺少包含标头。

  4. 缺少

    struct MyS
    声明。

  5. 使用符号常量而不是魔法值(

    16
    )。

这是生成的代码:

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

enum {
    OTHER_LEN = 16
};

struct MyS {
    int first;
    char other[OTHER_LEN];
};

char *readSlice (char *buf, int pos, int len) {
    return strndup(buf + pos, len);
}

void writeSlice (char * str, char * buf, int pos, int len) {
    memcpy(buf + pos, str, len);
    free(str);
}

char *intToStr (int i, int l) {
    char * s = malloc(l);
    for (int j = 0; j < l; j++) {
        *(s + j) = (i / pow(10, l - j - 1)) + '0';
        i = i % (int) pow(10, l - j - 1);
    }
    return s;
}

int strToInt (char * s, int l) {
    printf("%s\n", s);
    int i = 0;
    for (int j = 0; j < l; j++) {
        i += (*(s + j) - '0') * pow(10, l - j - 1);
    }
    free(s);
    return i;
}

void ReadString (char * s) {
    struct MyS *n = malloc(sizeof *n);
    n->first = strToInt(readSlice(s, 0, 4), 4);
    for (int i = 1; i < OTHER_LEN; i++) {
        printf("%d\n", i);
        (n->other)[i] = strToInt(readSlice(s, i * 4, 4), 4);
    }
}

int main(void) {    
    ReadString("0000000100020003000400050006000700080009001000110012001300140015");
}

和输出:

0000
1
0001
2
0002
3
0003
4
0004
5
0005
6
0006
7
0007
8
0008
9
0009
10
0010
11
0011
12
0012
13
0013
14
0014
15
0015
© www.soinside.com 2019 - 2024. All rights reserved.