【问题标题】:Why is there a segmentation dump when using the char pointer str1 instead of str?为什么使用 char 指针 str1 而不是 str 时会出现分段转储?
【发布时间】:2023-04-15 12:44:01
【问题描述】:

我使用这段代码来创建一个 Padding RSA 函数。不幸的是在替换时

mpz_get_str(str, base, N.get_mpz_t());
cout<<"\n\nLength of k = Modulus in bytes: "<<strlen(str);

str 和 str1 我收到分段转储。为什么会这样?

int main(const int argc, const char *const argv[])
{
// Check number of arguments
if (argc!=4){
printf("usage: %s [Message] [Exponent] [Modulus] \n", argv[0]);
return 1;
}
char *str;
char *str1="";
int base=10,l;
mpz_t op;

// Receive arguments
const mpz_class m(argv[1]), d(argv[2]),N(argv[3]),message(argv[1]);
mpz_get_str(str1, base, N.get_mpz_t());
cout<<"\n\nLength of k = Modulus in bytes: "<<strlen(str1);

// Calculate RSA
cout<<endl<<RSA(m,d,N);

//TestArea
cout<<"\n\n"<<m;
mpz_get_str(str, base, m.get_mpz_t());
cout<<"\n\nLength of string message in bytes: "<<strlen(str);
cout<<"\n\n"<<str;
return 0;
}

【问题讨论】:

    标签: c++ pointers char gmp


    【解决方案1】:

    有两个错误(至少)。您已将字符串文字传递给 mpz_get_str。

    char *str1="";
    mpz_get_str(str1, base, N.get_mpz_t());
    

    字符串文字不可修改。

    其次,即使字符串文字是可修改的,您也没有分配足够的内存来保存您的号码。

    第三个错误是概念性的。看来您想知道N 占用的字节数,这段代码即使在工作时也不会告诉您。

    这是确定N占用字节数的代码

    size_t num_bytes = mpz_size(N.get_mpz_t())*sizeof(mp_limb_t);
    

    num_bytes 将是 GMP 内部使用的字节数,用于存储数字 N 的大小。

    【讨论】:

      【解决方案2】:

      如果 str 为 NULL,则使用当前分配函数分配结果字符串(请参阅自定义分配)。该块将是 strlen(str)+1 个字节,对于字符串和空终止符来说已经足够了。

      如果 str 不为 NULL,它应该指向一个足够大的存储块来存储结果,即 mpz_sizeinbase (op, base) + 2。两个额外的字节用于可能的减号和空终止符.

      来自https://gmplib.org/manual/Converting-Integers.html

      当您将str1 传递给mpz_get_str 因为它不是NULL 并且此函数期望str1 指向一个有足够空间用于结果的缓冲区时,当mpz_get_str 尝试时将发生段错误将数据移动到str1 指向的假定缓冲区。

      一个可能的解决方案是:

      vector<char> str1(mpz_sizeinbase (N.get_mpz_t(), base) + 2);
      mpz_get_str(str1.data(), base, N.get_mpz_t());
      

      【讨论】:

      • 谢谢大家! str1(mpz_sizeinbase(N.get_mpz_t(), base) + 2)中+2的目的是什么?
      • @user11903678 它在文档和我引用的文本中“The two extra bytes are for a possible minus sign, and the null-terminator.”。
      • 谢谢 ddecos。还有一个问题:当我使用函数将 tet 转换为数字时,我想我可以让符号字节到 soide。你同意吗,这样做会有什么缺点吗?我的意思是我将使用一个额外的字节作为字符串的结尾,但不需要符号字节,因为所有字母都在 8 bist 上表示为正数?
      • @user11903678 “tet”和“soide”是什么意思?我没听懂你问什么。
      • 抱歉有错别字。还有一个问题:当我使用函数来转换数字中的字母时,我想我可以让符号字节放在一边。你同意吗,这样进行会有什么坏处吗?我的意思是我将使用一个额外的字节作为字符串的结尾,但不需要符号字节,因为所有字母都以 8 位表示为正数?
      最近更新 更多