为什么在调试时我的代码可以运行,但是在按build&run时却崩溃?

问题描述

因此我们得到了一个uni作业来格式化文本。 一行的最大宽度应为68个字符,如果单词不能填满该行,我们必须在空白处填充空白,并在最左端和最右端之间平均分布。

问题是当我生成并运行该程序时,它崩溃了,但是当我对其进行调试时,它运行正常。

我的编译器是Codeblocks 17.12,并使用minGW gdb调试即时消息。 我是编程新手,并且知道我的代码不是最出色的。 我们从教授那里得到了readtext函数

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

#define WORDS_LIMIT 10000

//------------------------------------------------------------
int readtext(const char* filename,int *maxWidth,char *words[],const int WordsLimit){
    int WordCount=0;
    FILE* Infile;
    Infile=fopen(filename,"r");
    assert(Infile);
    fscanf(Infile,"%i\n",maxWidth);
    char line[BUFSIZ];

    while (fgets(line,BUFSIZ,Infile) && WordsLimit>WordCount)
    {
    // remove newline
    char *newline = strchr(line,'\n');
    if (newline) {
        *newline = '\0';
    }
        words[WordCount++]=strdup(line);
    }
    return WordCount-1;
}
//------------------------------------------------------------
int letterCount (char *Zeile[],int wordCount){

  int wordWidth = 0;
  int i = 0;

  while (i <= wordCount){
    if (strlen(Zeile[i]) > 0 && strlen(Zeile[i]) < 68 ){
        wordWidth = wordWidth + strlen(Zeile[i]);
        i++;
    }else{
        i++;
        break;
    }
  }
  return wordWidth;
}
//------------------------------------------------------------
int findWords(char *Zeile[],char *words[]){

    int Width = 0;
    int k = 0;
    int wordsPerLine = 0;

    while (Width <= 68 && strlen(words[k]) > 0) {
        Width = strlen(words[k]) + 1;
        Zeile[k] = words[k];
        wordsPerLine = wordsPerLine+1;
        k++;
    }
    return wordsPerLine;
}
//------------------------------------------------------------
int formatBlanksLine (int lettersPerLine,int wordCount){

    int BlanksPerLine = 0;

    BlanksPerLine = 68 - (lettersPerLine + wordCount);

    return BlanksPerLine;
}
//------------------------------------------------------------
int formatBlanksRight(int BlanksLine,int BlanksRight){

    if (BlanksLine % 2 == 0){
        BlanksRight = (BlanksLine / 2) - 1;
    }
    else{
        BlanksRight = (BlanksLine / 2) - 2;
    }
return BlanksRight;
}
//------------------------------------------------------------
int formatBlanksLeft(int BlanksLine,int BlanksLeft){


    if (BlanksLine % 2 == 0){
        BlanksLeft = (BlanksLine / 2);
    }
    else{
        BlanksLeft = (BlanksLine / 2) + 1;
    }
return BlanksLeft;
}
//------------------------------------------------------------
int main(int argc,char *argv[]){
    char *Zeile[68];
    char *filename = "Cathedral_1.txt";
    char *words[WORDS_LIMIT];
    int wordCount = 0;
    int NumWords = 0;
    int maxWidth;
    int lettersPerLine = 0;
    int BlanksLine = 0;
    int BlanksLeft = 0;
    int BlanksRight = 0;
//------------------------------------------------------------
    // use filename from commandline
    if (argc > 1) {
    filename = argv[1];
    }
    // overwrite textwidth with the 2nd argument from the commandline
    if (argc > 2) {
    maxWidth = atoi(argv[2]);
    }
//------------------------------------------------------------
    NumWords = readtext(filename,&maxWidth,words,WORDS_LIMIT);
    wordCount = findWords(Zeile,words);
    lettersPerLine = letterCount(Zeile,wordCount);
    BlanksLine = formatBlanksLine(lettersPerLine,wordCount);
    BlanksLeft = formatBlanksLeft(BlanksLine,BlanksLeft);
    BlanksRight = formatBlanksRight(BlanksLine,BlanksRight);
//------------------------------------------------------------
    printf("Format text to %d chars per line\n",maxWidth);

    for (int i=0; i < NumWords; i++)
    {
    printf("%s\n",words[i]);
    }
//------------------------------------------------------------
    printf("-----------------------------------\n");
    for (int i = 0; i < BlanksLeft; i++){
        printf("0");
    }

    for (int i=0; i < wordCount ; i++)
    {
        printf("%s0",Zeile[i]);
    }

    for (int i = 0; i < BlanksRight; i++){
        printf("0");
    }
//------------------------------------------------------------
    printf("\n-----------------------------------\n");
    printf("Die Anzahl der Buchstaben ist: %d\n",lettersPerLine);
    printf("-----------------------------------\n");

//------------------------------------------------------------
    return 0;
 }

Cathedral.txt

The Cathedral and the Bazaar

Linux is subversive. Who would have thought even five years ago (1991) that a world-class operating system Could coalesce as if by magic out of part-time hacking by several thousand developers scattered all over the planet,connected only by the tenuous strands of the Internet?

Certainly not I. By the time Linux swam onto my radar screen in early 1993,I had already been involved in Unix and open-source development for ten years. I was one of the first GNU contributors in the mid-1980s. I had released a good deal of open-source software onto the net,developing or co-developing several programs (nethack,Emacs's VC and GUD modes,xlife,and others) that are still in wide use today. I thought I knew how it was done.

Linux overturned much of what I thought I knew. I had been preaching the Unix gospel of small tools,rapid prototyping and evolutionary programming for years. But I also believed there was a certain critical complexity above which a more centralized,a priori approach was required. I believed that the most important software (operating systems and really large tools like the Emacs programming editor) needed to be built like cathedrals,carefully crafted by individual wizards or small bands of mages working in splendid isolation,with no beta to be released before its time.

Linus Torvalds's style of development-release early and often,delegate everything you can,be open to the point of promiscuity-came as a surprise. No quiet,reverent cathedral-building here-rather,the Linux community seemed to resemble a great babbling bazaar of differing agendas and approaches (aptly symbolized by the Linux archive sites,who'd take submissions from anyone) out of which a coherent and stable system Could seemingly emerge only by a succession of miracles.

The fact that this bazaar style seemed to work,and work well,came as a distinct shock. As I learned my way around,I worked hard not just at individual projects,but also at trying to understand why the Linux world not only didn't fly apart in confusion but seemed to go from strength to strength at a speed barely imaginable to cathedral-builders.

By mid-1996 I thought I was beginning to understand. Chance handed me a perfect way to test my theory,in the form of an open-source project that I Could conscIoUsly try to run in the bazaar style. So I did-and it was a significant success.

This is the story of that project. I'll use it to propose some aphorisms about effective open-source development. Not all of these are things I first learned in the Linux world,but we'll see how the Linux world gives them particular point. If I'm correct,they'll help you understand exactly what it is that makes the Linux community such a fountain of good software-and,perhaps,they will help you become more productive yourself.

Cathedral_1.txt

68
The
Cathedral
and
the
Bazaar

Linux
is
subversive.
Who
would
have
thought
even
five
years
ago
(1991)
that
a
world-class
operating
system
Could
coalesce
as
if
by
magic
out
of
part-time
hacking
by
several
thousand
developers
scattered
all
over
the
planet,connected
only
by
the
tenuous
strands
of
the
Internet?

Certainly
not
I.
By
the
time
Linux
swam
onto
my
radar
screen
in
early
1993,I
had
already
been
involved
in
Unix
and
open-source
development
for
ten
years.
I
was
one
of
the
first
GNU
contributors
in
the
mid-1980s.
I
had
released
a
good
deal
of
open-source
software
onto
the
net,developing
or
co-developing
several
programs
(nethack,Emacs's
VC
and
GUD
modes,and
others)
that
are
still
in
wide
use
today.
I
thought
I
knew
how
it
was
done.

Linux
overturned
much
of
what
I
thought
I
knew.
I
had
been
preaching
the
Unix
gospel
of
small
tools,rapid
prototyping
and
evolutionary
programming
for
years.
But
I
also
believed
there
was
a
certain
critical
complexity
above
which
a
more
centralized,a
priori
approach
was
required.
I
believed
that
the
most
important
software
(operating
systems
and
really
large
tools
like
the
Emacs
programming
editor)
needed
to
be
built
like
cathedrals,carefully
crafted
by
individual
wizards
or
small
bands
of
mages
working
in
splendid
isolation,with
no
beta
to
be
released
before
its
time.

Linus
Torvalds's
style
of
development-release
early
and
often,delegate
everything
you
can,be
open
to
the
point
of
promiscuity-came
as
a
surprise.
No
quiet,reverent
cathedral-building
here-rather,the
Linux
community
seemed
to
resemble
a
great
babbling
bazaar
of
differing
agendas
and
approaches
(aptly
symbolized
by
the
Linux
archive
sites,who'd
take
submissions
from
anyone)
out
of
which
a
coherent
and
stable
system
Could
seemingly
emerge
only
by
a
succession
of
miracles.

The
fact
that
this
bazaar
style
seemed
to
work,and
work
well,came
as
a
distinct
shock.
As
I
learned
my
way
around,I
worked
hard
not
just
at
individual
projects,but
also
at
trying
to
understand
why
the
Linux
world
not
only
didn't
fly
apart
in
confusion
but
seemed
to
go
from
strength
to
strength
at
a
speed
barely
imaginable
to
cathedral-builders.

By
mid-1996
I
thought
I
was
beginning
to
understand.
Chance
handed
me
a
perfect
way
to
test
my
theory,in
the
form
of
an
open-source
project
that
I
Could
conscIoUsly
try
to
run
in
the
bazaar
style.
So
I
did-and
it
was
a
significant
success.

This
is
the
story
of
that
project.
I'll
use
it
to
propose
some
aphorisms
about
effective
open-source
development.
Not
all
of
these
are
things
I
first
learned
in
the
Linux
world,but
we'll
see
how
the
Linux
world
gives
them
particular
point.
If
I'm
correct,they'll
help
you
understand
exactly
what
it
is
that
makes
the
Linux
community
such
a
fountain
of
good
software-and,they
will
help
you
become
more
productive
yourself.

解决方法

这是我的主要评论开头。

好吧...

letterCount中,您拥有:

while (i <= wordCount)

这超出了数组的末尾。您想要的是:

while (i < wordCount)

第一个版本会出现段错误,因为Zeilechar pointers 的数组,我们会遇到未初始化的指针。

UB。因此,它尝试取消对 的引用。在调试下,它 still 的值是错误的,但是以某种方式,该值是“无害的”(例如, not segfault确实没有)。

正如我在主要评论中提到的那样,我们仍然要更改:

char *Zeile[68];

进入:

char *Zeile[WORDS_LIMIT];