我正在做我的学校项目,最近我一直在努力寻找代码中的细分错误。您能帮我检查一下代码吗?输入的是“ 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
答案 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);
这些更改导致相同的输出,但没有例外:
EDIT 解决评论中的问题:
以下代码创建了bool **scramble
,strlen("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);
}