c++ - C++ W:使用子线程的运行映像
问题描述
错误消息:
程序在 0x77dc2f6a 处
停止它以 SIGSEGV 信号停止,分段错误。
(gdb) 使用子线程 2120.0x20d8 的运行镜像。程序在 0x77dc2f6a 处
停止它以 SIGSEGV 信号停止,分段错误。
编译器:C-Free
这是我的代码
#include<stdio.h>
using namespace std;
/*
128m
n: [6,40] k: [1,6]
n*k: 0.9k
*/
struct BN
{
char num[160];
int len;
};
int len, num_k;
BN number;
BN* map;
bool* isC;
void BN_get(BN* bn, int len);
void BN_show(BN* bn);
void BN_clear(BN* bn);
// compare
bool BN_gt(BN* a, BN* b);
// count
void BN_mul(BN* a, BN* b, BN* c, int aS, int aE, int bS, int bE);//c = a+b
void f(int n, int k);
int main()
{
int i, j;
char c;
scanf("%d %d", &len, &num_k);
BN_get(&number, len);
map = new BN[len*num_k];
isC = new bool[len*num_k];
for(i=0;i<len*num_k;++i)
isC[i]=false;
// init
for(i=0; i<len; ++i){
//map[i,0]
for(j=0;j<=i;++j){
map[i*num_k].num[j] = number.num[j];
}
map[i*num_k].len = i+1;
isC[i*num_k] = true;
}
//printf("");//case1
f(len-1, num_k);
BN_show(&map[len*num_k]);
return 0; // line 63
}
void BN_get(BN* bn, int len)
{
int i;
char c;
c = getchar();
for(i=len-1;i>=0;--i){
scanf("%c", &c);
if(i>159 || i<0)printf("OUT\n");//debug
bn->num[i] = c-'0';
}// line 85
bn->len = len;
}
void BN_show(BN* bn)
{
int i, len=bn->len;
for(i=len-1;i>=0;--i){
if(i>159 || i<0)printf("OUT\n");//debug
printf("%d", bn->num[i]);
}
}
void BN_clear(BN* bn)
{
int i;
for(i=0;i<160;++i){
if(i>159 || i<0)printf("OUT\n");//debug
bn->num[i]=0;
}
bn->len = 0;
}
bool BN_gt(BN* a, BN* b)
{
int i, an, bn;
int alen = a->len, blen=b->len;
// if a>b
if(blen>alen){
return false;
}else if(alen==blen){
for(i=alen-1; i>=0; --i){
if(i>159 || i<0)printf("OUT\n");//debug
an = a->num[i];
bn = b->num[i];
if(an>bn)
return true;
if(an<bn)
return false;
}
return false;
}
return true;
}
void BN_mul(BN* a, BN* b, BN* c, int aS, int aE, int bS, int bE)
{
int i, j, k, l;
char *an=a->num, *bn=b->num, *cn=c->num;
BN_clear(c);
for(i=bS, k=0; i<=bE; ++i, ++k){
for(j=aS,l=k; j<=aE; ++j,++l){
if(i>159 || i<0)printf("OUT\n");//debug
if(l>159 || l<0)printf("OUT\n");//debug
if(j>159 || j<0)printf("OUT\n");//debug
if(l+1>159 || l+1<0)printf("OUT\n");//debug
cn[l] += bn[i]*an[j];
cn[l+1] += cn[l]/10;
cn[l] %= 10;
}
}
if(l>159 || l<0)printf("OUT\n");//debug
if(cn[l]==0)
c->len = l;
else
c->len = l+1;
}
void f(int n, int k)
{
int i, up=n-1-(k-2);
BN max, a, b;
BN_clear(&max);
for(i=0;i<up;++i){
// b = f(n-1-i, k-1)
if(!isC[(n-1-i)*num_k+k-1])
f(n-1-i, k-1);
b = map[(n-1-i)*num_k+k-1];
// a = f(n-1-i, k-1) x num(n-i, n);
BN_mul(&b, &number, &a, 0, b.len-1, n-i, n);
// max
if(BN_gt(&a, &max))
max=a;
}
isC[n*num_k+k] = true;
map[n*num_k+k] = max;
}
BN_xxx() 是大数的一些操作
在 main 的末尾,这是代码行
"//printf("");//case1"
如果我不 printf(),我将收到错误消息。
如果我 printf(),即使打印空,它也不会出错。
我设置了很多检查,它认为永远不会超出范围。
我猜这个问题是关于 IO 流的,但我不知道发生了什么。
我再次在 msvs 中运行。这是堆栈
name language
ntdll.dll!00007ffbc22d4cfa() unknown
ntdll.dll!00007ffbc22dc806() unknown
ntdll.dll!00007ffbc22dcad1() unknown
ntdll.dll!00007ffbc2279a55() unknown
ntdll.dll!00007ffbc21f6db5() unknown
ntdll.dll!00007ffbc21f2b55() unknown
ucrtbased.dll!00007ffb6a341716() unknown
ucrtbased.dll!00007ffb6a3414cd() unknown
ucrtbased.dll!00007ffb6a34455f() unknown
ucrtbased.dll!00007ffb6a3a622b() unknown
ucrtbased.dll!00007ffb6a368e15() unknown
ucrtbased.dll!00007ffb6a3857c6() unknown
ucrtbased.dll!00007ffb6a37c085() unknown
ucrtbased.dll!00007ffb6a37c27b() unknown
ucrtbased.dll!00007ffb6a37cbd7() unknown
ucrtbased.dll!00007ffb6a39ea3b() unknown
ConsoleApplication1.exe!_vfprintf_l(_iobuf * const _Stream, const char * const _Format, __crt_locale_pointers * const _Locale, char * _ArgList) line 644 C++
ConsoleApplication1.exe!printf(const char * const _Format, ...) line 958 C++
ConsoleApplication1.exe!BN_show(BN * bn) line 85 C++
ConsoleApplication1.exe!main() line 63 C++
解决方案
你分配内存:
map = new BN[len*num_k];
这有效地创建了一个索引0
为len*num_k - 1
(包括)的数组,并map
指向该数组的第一个元素。
然后你打电话BN_show
:
BN_show(&map[len*num_k]);
向函数传递一个指向索引处结构的指针,该结构len*num_k
超出分配的数组的末尾!越界会导致未定义的行为。
您传递给BN_show
函数的指针根本无效,您需要修改代码以将指针传递给有效结构。
如果要打印map
数组的所有元素,请在其上使用循环,并BN_show
分别调用每个元素。
在相关的旁注中:不要手动分配数组,std::vector
而是使用。
我还建议您停止使用指针,而是直接使用对象(“值”)或引用。
最后,请找几本关于C++的好书,好好学习。现在,您似乎更多地将它用作增强的 C 编译器。
推荐阅读
- xml - 如何在此 XML/XSLT 中去除/添加名称空间/前缀?
- gcc - 使用 gcc 编译时没有创建分析数据
- jenkins - 如何使用 Jenkins 管道在多个平台上触发构建?
- java - 是否可以在 Google App Engine 环境中进行相互 SSL 身份验证?
- ios - UITableViewCell - 在动态表格视图中获取 UITextField 值
- javascript - 为什么在 AJAX 调用中无法访问 SESSION 变量?
- android - Firebase:一旦用户卸载应用 IOS 和 Android,我需要清理数据库
- python-3.x - python中的逻辑代码给出了错误的答案
- java - 无法启动 bean 'subProtocolWebSocketHandler';嵌套异常是 java.lang.IllegalArgumentException: No handlers
- awk - awk:为什么四舍五入不适用于范围?