/MT и / MD создает катастрофический отказ, но только когда отладчик не присоединяется: как отладить? [дубликат]

Ниже приведен собственный код с комментариями. Извините, я не зашел так далеко, чтобы проверить, может ли он на самом деле делать то, что вы хотите, если это будет исправлено.

Sub CurrentCode()

    Dim wsSyn As Worksheet
'    Dim base_Postion, reverse__BaseDirection As Range
    Dim base_Position, reverse__BaseDirection As Range
    Dim searchCol_AB, rangeUnion_Copy, rangeUnion_Paste As Range
    Dim Cell As Object

    Set wsSyn = Sheets("Syn_Calc")
    ' Since base_Position is a variant the line below assigns a range to it.
    Set base_Position = wsSyn.Range("K3")
    ' reverse__BaseDirection is declared as a range.
    ' Therefore this cariable is assigned a range as well
    Set reverse__BaseDirection = wsSyn.Range("L4")

    ' ==================================================
        ' The above concept is probably wrong.
        ' If you wish to search for the values in K3 and L4
        ' you should have declared both variables as Strings or Variants
        ' and assigns the respective ranges' Values to them, such
        ' base_Position = wsSyn.Range("K3").Value
    ' ==================================================


    ' searchCol_AB is declared as a Variant and can therefore be assigned anything.
    ' If you wanted to assign a range to it, the Set statement would be required, like
    ' Set searchCol_AB = wsSyn.Range("A3:B100")
    ' since you omit the Set statement VBA will presume that you mean to
    ' assign the property of wsSyn.Range("A3:B100").
    ' Since you don't specify which property you mean, VBA will assign
    ' the default property which is Value.
    searchCol_AB = wsSyn.Range("A3:B100")

    ' ==================================================
        ' The above facts propbably don't fit your intentions.
        ' Since searchCol_AB is intended to be searched it should be a range.
        ' Therefore: Dim searchCol_AB As Range
        ' and Set searchCol_AB = wsSyn.Range("A3:B100")
    ' ==================================================

    ' rangeUnion_Copy is dimensioned as a Variant
    ' Yes, you can assign a range object to it but why not declare it as a Range?
    Set rangeUnion_Copy = Union(Cells(, 4), Cells(, 5), Cells(, 6))
    Set rangeUnion_Paste = Union(Cells(, 11), Cells(, 12), Cells(, 13))

    ' ==================================================
        ' Cells(, 4) misses the row number.
        ' VBA will correct the error and insert 1 instead.
        ' Therefore, Union(Cells(, 4), Cells(, 5), Cells(, 6))
        ' is equivalent to Union(Cells(1, 4), Cells(1, 5), Cells(1, 6))
        ' is equivalent to Range("D1:F1")

        ' Application.Union creates a range consisting of incontiguous cells
        ' like Union(Cells(1, 4), Cells(1, 6))
        ' Range("D1:F1") is just a normal range, not a Union.
        ' you might use Set rangeUnion_Copy = Range(Cells(1, 4), Cells(1, 6))
        ' if you need to change thr rows in a loop that might look like
        ' Set rangeUnion_Copy = Range(Cells(R, 4), Cells(R, 6))
        ' where R is the For ... Next loop counter
    ' ==================================================


    ' your code fails on the next line because
    ' searchCol_AB holds the values of range wsSyn.Range("A3:B100"),
    ' not the range itself.
    For Each Cell In searchCol_AB
        ' ==================================================
            ' A range can have many cells.
            ' the smallest range has a single cell.
            ' Ergo, a cell is a range.
            ' True, a range is an object.
            ' By declaring Cell as an Object you are employing what
            ' is called "late binding", meaning VBA only finds out
            ' which kind of object (Range) it is when it is used.
            ' You might find late binding beyond the scope of your current
            ' knowledge and therefore declare a range as a range for the time being.
        ' ==================================================

        If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
            ' base_Position is a variable of variant type to which a range was assigned.
            ' Therefore base_Position is a range object.
            ' UCase([Range object]) is impossible.
            ' Therefore VBA executes UCase([Range_object.Value])
            ' That gives the result you intend but in a way you didn't understand.
            ' Better to avoid the use of default properties.

        ' ==================================================
            ' If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
            ' is a common logical error. The correct syntax is
            ' If Cell.Value = UCase(base_Position) And Cell.Value = UCase(reverse__BaseDirection) Then
            ' some programmers would add parentheses for better clarity, thus:-
            ' If (Cell.Value = UCase(base_Position)) And (Cell.Value = UCase(reverse__BaseDirection)) Then
            ' Note that each expressions is evaluated to True or False.
        ' ==================================================

            ' The Copy command requires specification of a Destination cell.
            ' Destination is either a single cell (better, since less prone to errors)
            ' or a range of equal size to the copied range.
            ' It can't be a string, such as rangeUnion_Paste.Address
            ' (The Address property always holds a String)
            rangeUnion_Copy.Copy rangeUnion_Paste.Address

        ' ==================================================
            ' The way you have set rangeUnion_Paste it is of equal size
            ' to rangeUnion_Copy. Therefore either of the following would work.
            ' rangeUnion_Copy.Copy Destination:= Range(rangeUnion_Paste.Address)
            ' rangeUnion_Copy.Copy Destination:= rangeUnion_Paste
            ' rangeUnion_Copy.Copy Destination:= rangeUnion_Paste.Cells(1)
        ' ==================================================

        End If
    Next Cell           ' better specify which "Next" is called
End Sub
9
задан BIBD 4 May 2009 в 15:34
поделиться

3 ответа

Одно небольшое отличие между работой с подключенным отладчиком или без него - это Куча отладки ОС (см. Также Почему мой код работает медленно, когда у меня подключен отладчик ?). Вы можете отключить кучу отладки, используя переменную окружения _NO_DEBUG_HEAP. Вы можете указать это либо в свойствах своего компьютера, либо в настройках проекта в Visual Studio.

Как только вы отключите кучу отладки, вы увидите такое же падение даже при подключенном отладчике.

Тем не менее, обратите внимание на память ошибки могут быть трудно отладить,

12
ответ дан 4 December 2019 в 11:44
поделиться

Сбой внутри new или malloc обычно является подсказкой что (внутренняя) структура реализации malloc была повреждена. Это в большинстве случаев выполняется путем записи за предыдущее распределение (переполнение буфера). Затем при следующем вызове new или malloc происходит сбой приложения, поскольку внутренняя структура теперь содержит недопустимые данные.

Проверьте, не можете ли вы перезаписать любое предыдущее выделенное пространство.

2
ответ дан 4 December 2019 в 11:44
поделиться

Верификатор приложения был очень полезен для решения этой проблемы, когда у меня в среде было _NO_DEBUG_HEAP = 1, см. Принятый ответ здесь: Поиск места, где память была в последний раз освобождена?

Вероятно, также стоит упомянуть pageheap , который я нашел, глядя на Application Verifier. Похоже, что он охватывает некое подобное основание.

(к вашему сведению, это было переполнение буфера из одного символа:

m_pEnumName = (char*)malloc(strlen(data) /* missing +1 here */);
strcpy(m_pEnumName, data);

... еще один смехотворно хороший аргумент, чтобы не использовать strcpy напрямую.)

4
ответ дан 4 December 2019 в 11:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: