gpt4 book ai didi

c - 在 ruby​​ 上调用 c 函数时出现段错误

转载 作者:行者123 更新时间:2023-11-30 17:22:46 27 4
gpt4 key购买 nike

我正在尝试使用 C 函数扩展我的 Ruby 代码。 C 代码编译时不会发出警告。但是当我尝试运行 ruby​​ 代码时,出现段错误:

我有这个c代码:

#include <ruby.h>

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

#include "nessie.h"

/* #define TRACE_INTERMEDIATE_VALUES */

/*
* The number of rounds of the internal dedicated block cipher.
*/
#define R 10

VALUE rb_mExample;
VALUE rb_cClass;

// ...

static char* displayHash(const unsigned char array[], int length){
int i, k;
char *str;

str = malloc(3 * length + 1);
if (str == NULL) {
return NULL;
}

k = 0;
str[0] = '\0';
for (i = 0; i < length; i++){
char hex[3];

if (i % 32 == 0){
str[k++] = ' ';
}

if (i % 8 == 0){
str[k++] = ' ';
}
snprintf(hex, sizeof(hex), "%02X", array[i]);

str[k++] = hex[0];
str[k++] = hex[1];
}

str[k] = '\0';

return str;
}


VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];

int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;

NESSIEinit(&w);
NESSIEadd((u8*)valor, 8*sizeo, &w);
NESSIEfinalize(&w, digest);

return (VALUE) displayHash(digest, DIGESTBYTES);
}

void
Init_example(){
rb_mExample = rb_define_module("Example");
rb_cClass = rb_define_class_under(rb_mExample, "Class", rb_cObject);

rb_define_method(rb_cClass, "print_string", print_string, 1);
}

以及这个 Ruby 代码:

require "example"

def print
e = Example::Class.new
e.print_string("ruby")
end

当我运行 ruby​​ 代码时,出现段错误。

编辑:带有日志信息的要点

https://gist.github.com/psantos10/f07484afa26ce0e55181

我哪里失败了?我是 C 语言新手。

编辑:

我将“print_string”更改为如下所示:

VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];

int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;

NESSIEinit(&w);
NESSIEadd((u8*)valor, 8*sizeo, &w);
NESSIEfinalize(&w, digest);

return rb_str_new(displayHash(digest, DIGESTBYTES), 128);
}

这样,段错误就消失了。但返回的字符串带有奇怪的字符,例如:

"ruby\x00\x00\x00\x00\x00No error detected.\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD80x\xC0\x18`\x18\x18&F\xAF\x05#\x8C##\xB8\x91\xF9~\xC6?\xC6\xC6\xFB\xCDo\x13\xE8\x87\xE8\xE8\xCB\x13\xA1L\x87&\x87\x87\x11mb\xA9\xB8\xDA\xB8\xB8\t\x02\x05\b\x01\x04\x01\x01\r\x9EnBO!OO\x9Bl\xEE\xAD6\xD866\xFFQ\x04Y\xA6\xA2\xA6\xA6\f\xB9\xBD\xDE\xD2o\xD2"

当正确的必须是:

"ruby"

编辑3:

进行此更改:

VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
/*
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
*/
NESSIEinit(&w);
NESSIEadd((u8*)"ruby", 8*4, &w);
NESSIEfinalize(&w, digest);

return rb_str_new(displayHash(digest, DIGESTBYTES), 128);
}

返回正确的值。

然后我尝试这样做:

VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
/*
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
*/
NESSIEinit(&w);
NESSIEadd((u8*)"ruby", 8*4, &w);
NESSIEfinalize(&w, digest);

return rb_str_new2(valor);
}

期望返回“ruby”字符串。但不是。它返回:“\x05”

这是什么意思?

最佳答案

for (i = 0; i < length; i++)

在这个循环中,对于每个传递的 if 条件,您都会增加 k,因此通过这样做,您将获得数组越界访问,从而导致崩溃。

确保

char *str = malloc( 3 * length + 1);

不是

char *str = malloc( 3 * (length + 1));

例如:

值为length = 2;

char *str = malloc(7);

现在,在 for 循环中,将 k 增加 4 次。

k = 4;

现在,在第二次迭代之后,如果退出循环,则

k=8;

因此 str[8] 不是有效的访问,可能会导致崩溃

关于c - 在 ruby​​ 上调用 c 函数时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27886212/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com